Здесь собраны 20 основных направлений: от переменных, циклов и ООП до многопоточности, работы с БД, Spring Boot, JVM и современных возможностей Java.
Используйте её как roadmap для обучения, чек-лист для повторения или ориентир при подготовке к собеседованиям.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍3🔥2
Считаем частоту слов через Stream API!
Иногда нужно понять, сколько раз каждое значение встречается в списке: слова в тексте, статусы заказов, ошибки в логах или действия пользователей.
Допустим, есть список слов:
Можно вручную создать Map и увеличивать счётчик:
Но через Stream API это можно записать короче:
Function.identity() означает: группируем элементы по самому значению.
А Collectors.counting() считает, сколько элементов попало в каждую группу.
Результат будет таким:
Такой подход удобно использовать для аналитики, логов, статистики, тегов, категорий и любых повторяющихся значений.
👉 Java Ready | #практика
Иногда нужно понять, сколько раз каждое значение встречается в списке: слова в тексте, статусы заказов, ошибки в логах или действия пользователей.
Допустим, есть список слов:
List<String> words = List.of(
"java", "spring", "java", "api", "spring", "java"
);
Можно вручную создать Map и увеличивать счётчик:
Map<String, Long> result = new HashMap<>();
for (String word : words) {
result.put(word, result.getOrDefault(word, 0L) + 1);
}
Но через Stream API это можно записать короче:
Map<String, Long> result = words.stream()
.collect(Collectors.groupingBy(
Function.identity(),
Collectors.counting()
));
Function.identity() означает: группируем элементы по самому значению.
А Collectors.counting() считает, сколько элементов попало в каждую группу.
Результат будет таким:
{spring=2, java=3, api=1}
Такой подход удобно использовать для аналитики, логов, статистики, тегов, категорий и любых повторяющихся значений.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍3🔥3
Выражение
arr[i] используется для доступа к элементу массива по индексу. Запись arr[i] = value изменяет значение элемента по указанному индексу.На картинке показаны базовые операции с массивами, которые часто используются в практике и на собеседованиях.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10❤4👍2
Почему isBlank() часто полезнее, чем isEmpty()?
В Java строки можно проверять по-разному.
Например, isEmpty() проверяет только длину строки:
То есть строка из пробелов для isEmpty() уже не пустая.
А в пользовательском вводе такое встречается постоянно: имя, комментарий, email, заголовок, поле поиска.
Для таких случаев лучше подходит isBlank():
isBlank() считает строку пустой, если в ней нет видимых символов.
Поэтому проверка становится надёжнее:
Если проверяешь пользовательский текст, isBlank() часто безопаснее, чем isEmpty().
👉 Java Ready | #совет
В Java строки можно проверять по-разному.
Например, isEmpty() проверяет только длину строки:
"".isEmpty(); // true
" ".isEmpty(); // false
То есть строка из пробелов для isEmpty() уже не пустая.
А в пользовательском вводе такое встречается постоянно: имя, комментарий, email, заголовок, поле поиска.
Для таких случаев лучше подходит isBlank():
"".isBlank(); // true
" ".isBlank(); // true
"\n\t".isBlank(); // true
isBlank() считает строку пустой, если в ней нет видимых символов.
Поэтому проверка становится надёжнее:
if (name == null || name.isBlank()) {
name = "Guest";
}Если проверяешь пользовательский текст, isBlank() часто безопаснее, чем isEmpty().
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🔥5👍3
В этой статье:
• Чем SSE отличается от polling и WebSocket
• Как сделать подписку клиента через text/event-stream
• Зачем Redis нужен для хранения подписок пользователейПродолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍3🔥3
Идеально для CLI, serverless и микросервисов.
Используй native-image, настраивай reflection-config.json и удивляйся, как твой код запускается быстрее Python-скрипта.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍4❤3
Когда собираешь Map через Stream API подумай про дубликаты ключей!
В Java часто нужно превратить список объектов в Map.
Например, есть пользователи, и хочется получить словарь id -> name:
Код выглядит нормально, пока в списке нет двух пользователей с одинаковым id.
Если дубликат появится, Java выбросит:
Поэтому, если дубликаты возможны, лучше сразу указать merge-функцию:
Здесь при совпадении ключей останется новое значение.
Можно сделать наоборот:
Тогда сохранится первое значение.
👉 Java Ready | #совет
В Java часто нужно превратить список объектов в Map.
Например, есть пользователи, и хочется получить словарь id -> name:
Map<Long, String> usersById = users.stream()
.collect(Collectors.toMap(User::id, User::name));
Код выглядит нормально, пока в списке нет двух пользователей с одинаковым id.
Если дубликат появится, Java выбросит:
IllegalStateException: Duplicate key
Поэтому, если дубликаты возможны, лучше сразу указать merge-функцию:
Map<Long, String> usersById = users.stream()
.collect(Collectors.toMap(
User::id,
User::name,
(oldName, newName) -> newName
));
Здесь при совпадении ключей останется новое значение.
Можно сделать наоборот:
(oldName, newName) -> oldName
Тогда сохранится первое значение.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍5🔥4
Примитивные типы хранят значение напрямую в переменной и работают без объектов. Ссылочные типы хранят ссылку на объект, при этом сам объект размещается в heap, а переменная указывает на него.
Также показано различие поведения при копировании: значение копируется целиком для примитивов и копируется ссылка для объектов.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍6❤5
Ищем самый дорогой товар через Stream API!
Допустим, есть список товаров, и нужно найти позицию с максимальной ценой.
Создадим простую модель:
Подготовим данные:
Можно пройтись циклом и вручную хранить текущий максимум:
Но через Stream API это можно сделать короче:
А
Поэтому результат лучше обработать явно:
Такой подход удобно использовать для товаров, заказов, рейтингов, зарплат, статистики и любых списков, где нужно найти максимальный объект по конкретному полю.
👉 Java Ready | #практика
Допустим, есть список товаров, и нужно найти позицию с максимальной ценой.
Создадим простую модель:
record Product(String name, BigDecimal price) {}Подготовим данные:
List<Product> products = List.of(
new Product("Keyboard", new BigDecimal("79.99")),
new Product("Mouse", new BigDecimal("39.99")),
new Product("Monitor", new BigDecimal("249.99"))
);
Можно пройтись циклом и вручную хранить текущий максимум:
Product top = products.get(0);
for (Product product : products) {
if (product.price().compareTo(top.price()) > 0) {
top = product;
}
}
Но через Stream API это можно сделать короче:
Optional<Product> top = products.stream()
.max(Comparator.comparing(Product::price));
Comparator.comparing(Product::price) говорит Java сравнивать товары по цене.А
max() возвращает Optional, потому что список может быть пустым.Поэтому результат лучше обработать явно:
Product product = top.orElseThrow();
Такой подход удобно использовать для товаров, заказов, рейтингов, зарплат, статистики и любых списков, где нужно найти максимальный объект по конкретному полю.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍3🔥3
В задаче нужно определить, закрыты ли все скобки. Порядок вложенности не проверяется, только равенство количества.
Сегодня в посте:
• Зададим строку;
• Посчитаем количество для каждого вида скобок;
• Проверим, что все счётчики равны нулю.
Такой способ подходит для простых проверок строк, где важен сам факт закрытия скобок, а не порядок.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍3❤2🤝1
Почему Collections.unmodifiableList() не всегда делает список неизменяемым?
На первый взгляд такой код надёжно защищает коллекцию:
Через languages действительно нельзя вызвать add() или remove(): Java выбросит UnsupportedOperationException.
Но unmodifiableList() не создаёт отдельную коллекцию. Он возвращает только неизменяемое представление исходного списка.
Поэтому изменение source будет видно и через languages. В примере программа выведет:
Если нужна независимая неизменяемая копия, лучше использовать List.copyOf():
Теперь последующие изменения source не затронут languages. Это особенно важно, когда список сохраняется в поле объекта или возвращается из публичного API.
Стоит учитывать ещё одну деталь: List.copyOf() не допускает null-элементы и сразу выбросит NullPointerException, если они есть в исходной коллекции.
👉 Java Ready | #совет
На первый взгляд такой код надёжно защищает коллекцию:
var source = new ArrayList<>(List.of("Java", "C++"));
var languages = Collections.unmodifiableList(source);
source.add("C#");
System.out.println(languages);Через languages действительно нельзя вызвать add() или remove(): Java выбросит UnsupportedOperationException.
Но unmodifiableList() не создаёт отдельную коллекцию. Он возвращает только неизменяемое представление исходного списка.
Поэтому изменение source будет видно и через languages. В примере программа выведет:
[Java, C++, C#]
Если нужна независимая неизменяемая копия, лучше использовать List.copyOf():
var languages = List.copyOf(source);
Теперь последующие изменения source не затронут languages. Это особенно важно, когда список сохраняется в поле объекта или возвращается из публичного API.
Стоит учитывать ещё одну деталь: List.copyOf() не допускает null-элементы и сразу выбросит NullPointerException, если они есть в исходной коллекции.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍5🔥3