Кто-нибудь когда-нибудь называл Джаву Ждавой? Неужели я первый это придумал только что?
(По-любому же должен был быть мем)
(По-любому же должен был быть мем)
🤡23🤨6😁1💊1
Прекратите использовать ArrayList
Я серьёзно. В 2022 году Java-программисту он не нужен практически никогда. Если в Java 8 ещё можно было оправдать его использование, потому что в стандартной библиотеке не было адекватной замены, то с Java 9 нужда в нём резко упала с введением неизменяемых коллекций.
Давайте я по полкам разберу все возможные варианты и покажу, как можно избежать использования ArrayList в большинстве случаев.
Мне нужно завести список, как это сделать?
Очень просто: заводите список с помощью List.of(). Либо если нужно создать список от существующей коллекции, то пишете List.copyOf(collection).
Пример:
Не вопрос. В Java 16 появилась возможность создавать иммутабельные списки с помощью Stream.toList(), который поддерживает null-элементы.
Пример:
Используйте Stream.builder().
Пример:
Ну а если мне всё-таки нужен изменяемый список? Мне надо хранить изменяемое состояние!
Используйте старый добрый метод Arrays.asList. Пример:
Вот только в этом случае используйте ArrayList. Если ни один из четырёх случаев выше вам не подходит (по моему личному опыту такое нужно чрезвычайно редко).
Помните, что наиболее правильный подход – это immutable by default. Это избавляет от большого класса ошибок и делает код легче для понимания. Начинайте решать задачу с использованием иммутабельности, и только если это не работает, переходите к мутабельности.
#arraylist
Я серьёзно. В 2022 году Java-программисту он не нужен практически никогда. Если в Java 8 ещё можно было оправдать его использование, потому что в стандартной библиотеке не было адекватной замены, то с Java 9 нужда в нём резко упала с введением неизменяемых коллекций.
Давайте я по полкам разберу все возможные варианты и покажу, как можно избежать использования ArrayList в большинстве случаев.
Мне нужно завести список, как это сделать?
Очень просто: заводите список с помощью List.of(). Либо если нужно создать список от существующей коллекции, то пишете List.copyOf(collection).
Пример:
var list = List.of(1, 2, 3);
var list2 = List.copyOf(col);Стоп, List.of() не поддерживает null-элементы, а мне это нужно!
Не вопрос. В Java 16 появилась возможность создавать иммутабельные списки с помощью Stream.toList(), который поддерживает null-элементы.
Пример:
var list = Stream.of(1, 2, null).toList();
А если мне нужно инициализировать список динамически? Я не могу использовать List.of/Stream.of, потому что не знаю количество элементов заранее!Используйте Stream.builder().
Пример:
var builder = Stream.<Integer> builder();Кстати, построение списка с помощью Stream.builder() эффективнее, чем через ArrayList. Об этом я писал тут.
builder.add(1);
builder.add(2);
if (condition) {
builder.add(3);
}
var list = builder.build().toList();
Ну а если мне всё-таки нужен изменяемый список? Мне надо хранить изменяемое состояние!
Используйте старый добрый метод Arrays.asList. Пример:
var list = Arrays.asList(1, 2, 3);Если нужно создать копию от существующей коллекции:
list.set(1) = 4;
var list = Arrays.asList(col.toArray(Integer[]::new))Мне нужен расширяемый список! Я хочу добавлять и удалять элементы!
Вот только в этом случае используйте ArrayList. Если ни один из четырёх случаев выше вам не подходит (по моему личному опыту такое нужно чрезвычайно редко).
Помните, что наиболее правильный подход – это immutable by default. Это избавляет от большого класса ошибок и делает код легче для понимания. Начинайте решать задачу с использованием иммутабельности, и только если это не работает, переходите к мутабельности.
#arraylist
👎31👍19🤔6🤮3🤡3⚡2❤1🔥1
Всего месяц остался до первой фазы Rampdown, а в JDK 20 до сих пор нет ни одного JEP'а. Понятно, что в релиз не могут не попасть всякие вторые инкубаторы и восьмые превью. Т.е. однозначно будут:
• JEP 433: Pattern Matching for switch (Fourth Preview)
• JEP 432: Record Patterns (Second Preview)
• JEP 434: Foreign Function & Memory API (Second Preview)
• JEP XXX: Virtual Threads (Second Preview)
• JEP XXX: Structured Concurrency (Second Incubator)
А вот новые фичи что-то не подвозят. Для меня наибольший интерес представляет JEP 430: String Templates (Preview), и он сейчас в активной разработке. Надеюсь, что он всё-таки успеет.
Второй – JEP 431: Sequenced Collections, и он тоже пока в разработке.
Ещё может попасть JEP 429: Scoped values (Incubator). Раньше он назывался Extent-Local Variables.
Итого, будет где-то 5-8 JEP'ов. Релиз будет вполне полноценным.
Ну и не забывайте, что даже если в релизе нет вообще ни одного JEP'а, то в любом случае присутствуют тысячи мелких улучшений, оптимизаций, исправлений багов и т.д. Например, будет ещё большее сокращение потребляемой памяти у G1. Так что повод обновляться до Java 20 будет!
#java20
• JEP 433: Pattern Matching for switch (Fourth Preview)
• JEP 432: Record Patterns (Second Preview)
• JEP 434: Foreign Function & Memory API (Second Preview)
• JEP XXX: Virtual Threads (Second Preview)
• JEP XXX: Structured Concurrency (Second Incubator)
А вот новые фичи что-то не подвозят. Для меня наибольший интерес представляет JEP 430: String Templates (Preview), и он сейчас в активной разработке. Надеюсь, что он всё-таки успеет.
Второй – JEP 431: Sequenced Collections, и он тоже пока в разработке.
Ещё может попасть JEP 429: Scoped values (Incubator). Раньше он назывался Extent-Local Variables.
Итого, будет где-то 5-8 JEP'ов. Релиз будет вполне полноценным.
Ну и не забывайте, что даже если в релизе нет вообще ни одного JEP'а, то в любом случае присутствуют тысячи мелких улучшений, оптимизаций, исправлений багов и т.д. Например, будет ещё большее сокращение потребляемой памяти у G1. Так что повод обновляться до Java 20 будет!
#java20
👍4🥱3🔥1🤯1
👍7🤔1
Полезное улучшение в Java 19: отдельная страница поиска по JavaDoc'у. До Java 19 можно было вводить строку поиска только в выпадающем меню. А сейчас можно, например, скинуть коллеге ссылку со строкой запроса: https://docs.oracle.com/en/java/javase/19/docs/api/search.html?q=map%20copyof.
Кроме того, теперь можно искать по нескольким словам. Например, если ввести "map copyof", то JavaDoc найдёт все сигнатуры, где встречаются и map, и copyof.
#java19 #javadoc
Кроме того, теперь можно искать по нескольким словам. Например, если ввести "map copyof", то JavaDoc найдёт все сигнатуры, где встречаются и map, и copyof.
#java19 #javadoc
👍12👌1
Наткнулся на интересный репозиторий, где сравнивается производительность программы, написанной на Котлине, с различными вариантами компиляции: Kotlin/Native, GraalVM CE Native, GraalVM EE Native, Kotlin/Wasm (WebAssembly). Ну и, конечно же, производится замер на обычной JVM. Программа вычисляет и печатает первые 500 пар простых чисел-близнецов. Замеряется время сборки (компиляции) программы и время её выполнения. Результаты замера смотрите в комменте к этому посту или пройдите по ссылке на GitHub.
Время сборки ожидаемо самое маленькое у JVM (потому что компиляция в байткод). А вот что оказалось неожиданным, так это то, что JVM ещё и быстрее всех выполнила программу! Быстрее, чем натив – это вообще как?? Вот так. И в этом нет ничего удивительного. Всё-таки в HotSpot JIT было вложено более 20 лет усилий сотен программистов, и там очень мощные оптимизации. А Kotlin/Native и GraalVM Native – очень молодые технологии, да и разработчиков там работает меньше в разы.
Можно ли закапывать Kotlin/Native и GraalVM Native после этого? Конечно же, нет.
Во-первых, это всего лишь один частный пример. На других примерах картина может быть обратной. Например, для короткоживущих программ AOT почти всегда будет давать лучший результат. Если в этом конкретном примере взять итераций не 500, а поменьше (допустим, 20), то натив должен отработать гораздо быстрее, т.к. не будет тратить время на чтение JAR, верификацию байткода, интерпретацию, профилирование, компиляцию и т.д.
Во-вторых, посмотрите на память. JVM жрёт больше всех. Это может быть критично для вашей задачи, например, для микросервисов.
В-третьих, для запуска программы требуется JVM, которую нужно таскать с собой. А она довольно тяжёлая. И это часто неудобно (а иногда невозможно). Что проще: послать клиенту маленький экзешник 570 килобайт, который он просто тыкнет, или набор джарок с JVM и инструкцией, как запускать эти джарки и какие ключи указывать?
В-четвёртых, (shipilev mode on) будьте аккуратней с бенчмарками. Они часто врут, особенно на синтетических примерах. Нужно тестировать реальное приложение в реальных условиях (shipilev mode off).
P.S. Если интересно поподробней узнать, почему конкретно в этом примере Kotlin/Native уступает, можете почитать оригинальный тред (внимание, 2018-й год – тогда Kotlin/Native был ещё медленнее).
#kotlin #graalvm #native
Время сборки ожидаемо самое маленькое у JVM (потому что компиляция в байткод). А вот что оказалось неожиданным, так это то, что JVM ещё и быстрее всех выполнила программу! Быстрее, чем натив – это вообще как?? Вот так. И в этом нет ничего удивительного. Всё-таки в HotSpot JIT было вложено более 20 лет усилий сотен программистов, и там очень мощные оптимизации. А Kotlin/Native и GraalVM Native – очень молодые технологии, да и разработчиков там работает меньше в разы.
Можно ли закапывать Kotlin/Native и GraalVM Native после этого? Конечно же, нет.
Во-первых, это всего лишь один частный пример. На других примерах картина может быть обратной. Например, для короткоживущих программ AOT почти всегда будет давать лучший результат. Если в этом конкретном примере взять итераций не 500, а поменьше (допустим, 20), то натив должен отработать гораздо быстрее, т.к. не будет тратить время на чтение JAR, верификацию байткода, интерпретацию, профилирование, компиляцию и т.д.
Во-вторых, посмотрите на память. JVM жрёт больше всех. Это может быть критично для вашей задачи, например, для микросервисов.
В-третьих, для запуска программы требуется JVM, которую нужно таскать с собой. А она довольно тяжёлая. И это часто неудобно (а иногда невозможно). Что проще: послать клиенту маленький экзешник 570 килобайт, который он просто тыкнет, или набор джарок с JVM и инструкцией, как запускать эти джарки и какие ключи указывать?
В-четвёртых, (shipilev mode on) будьте аккуратней с бенчмарками. Они часто врут, особенно на синтетических примерах. Нужно тестировать реальное приложение в реальных условиях (shipilev mode off).
P.S. Если интересно поподробней узнать, почему конкретно в этом примере Kotlin/Native уступает, можете почитать оригинальный тред (внимание, 2018-й год – тогда Kotlin/Native был ещё медленнее).
#kotlin #graalvm #native
👍16🔥5🤔2
Задачка от Heinz Kabutz.
Сколько массивов будет создано? Map<Integer, Integer> map = new HashMap<>(180); for (int i = 0; i < 180; i++) { map.put(i, i * i); }
Сколько массивов будет создано? Map<Integer, Integer> map = new HashMap<>(180); for (int i = 0; i < 180; i++) { map.put(i, i * i); }
Final Results
20%
180
25%
0
30%
1
25%
2
✍6☃3😢3👍1
В следующей версии IntelliJ IDEA (2023.1) появится автодополнение опций JVM в Run/Debug Configurations.
В выпадающем списке будут показываться опции, которые применимы к конкретной версии JVM. То есть они не захардкожены в Идее, а вычисляются динамически для текущей JVM. То есть там будут не только стандартные опции, но и нестандартные (-X и -XX:)
#IntelliJIDEA
В выпадающем списке будут показываться опции, которые применимы к конкретной версии JVM. То есть они не захардкожены в Идее, а вычисляются динамически для текущей JVM. То есть там будут не только стандартные опции, но и нестандартные (-X и -XX:)
#IntelliJIDEA
👍41
Какой вы используете JUnit?
Final Results
16%
JUnit 4
76%
JUnit 5
11%
Другой фреймворк
14%
Вообще не пишем тесты
Похоже, что 32-битная версия Java всё: https://openjdk.org/jeps/8303167
👍13🫡11👎1😢1
Ежегодный опрос. Какую версию(-и) Java или язык JVM вы используете на работе?
Final Results
20%
Java 8 или более старую
45%
Java 11
3%
Java 12-16
47%
Java 17
4%
Java 18+
4%
Groovy
3%
Scala
25%
Kotlin
1%
Clojure
👍7✍1