Java Interview Tasks
4.83K subscribers
212 photos
1 video
1 file
140 links
Реальные вопросы и задачи с собеседований.
Оригинальный авторский контент.
Актуальный материал.
Уровень вопросов от junior до supersenior.

Автор канала - @alexzelentsov

По рекламе: @alexzelentsov
Download Telegram
🔍 Ответ на задачу про исключение в стримах Java! 🚨

При выполнении данного кода возникнет исключение NullPointerException.
Давайте разберём, почему это происходит. 🤔

Код:
 
public static class Fee {
private String description;

public Fee(String description) {
this.description = description;
}

public String getDescription() {
return description;
}
}

public static void main(String[] args) {
List<Fee> fees = List.of(new Fee(null));
String s = fees.stream()
.map(Fee::getDescription)
.findFirst()
.orElse("1");
System.out.println(s);
}


Проблема возникает в строчке findFirst(). Метод .map(Fee::getDescription) создаёт стрим, где первый элемент имеет значение null из-за description равного null в объекте Fee.

Когда findFirst() пытается вернуть найденное значение — а это null — метод Optional.of() выбрасывает NullPointerException, поскольку Optional.of() не позволяет обёртывать null значениями. Для обработки null значений нужно использовать Optional.ofNullable().

Чтобы исправить это и избежать исключения, можно немного изменить этот код:

String s = fees.stream()
.map(Fee::getDescription)
.filter(Objects::nonNull) // добавляем этот фильтр
.findFirst()
.orElse("1");
Этот код сначала фильтрует все null значения из стрима и предотвращает NullPointerException.

Если вам понравился разбор, не забудьте поставить лайк, подписаться и оставить комментарий! 😊

#streamAPI #nullHandling #java_interview_tasks
🔥22👍12❤2🤝1
🔍 Ответ на задачу про Stream.peek(): Почему ничего не напечаталось? 🕵️‍♂️

Метод peek() часто используют для логирования промежуточных этапов стрима. Но новички часто забывают про "ленивость" стримов.

Объяснение: Стримы в Java ленивы. Промежуточные операции (filter, map, peek) не выполняются до тех пор, пока не будет вызвана терминальная операция (collect, forEach, count и т.д.). В данном коде терминальной операции нет, поэтому конвейер даже не запустится.

Вывод: Код не выведет ничего. Чтобы peek сработал, нужно добавить, например, .collect(Collectors.toList()) в конце.
⚡️ Не перепутайте:
peek() предназначен для отладки, не используйте его для изменения состояния объектов (side-effects).

Всегда завершайте цепочку стрима терминальной операцией.

#java #streamapi #peek #lazy #backend #интервью #java_interview_tasks
🔥7❤4
🔍 Ответ на задачу про Collectors.toMap 💥

Дефолтная версия Collectors.toMap(keyMapper, valueMapper) предполагает, что ключи уникальны. Если встречается дубликат (и "apple12", и "apricot" имеют длину 7), метод выбрасывает IllegalStateException: Duplicate key.

Вывод:
Чтобы код не падал, нужно использовать перегруженную версию с "merge function":
.collect(Collectors.toMap(s -> s.length(), s -> s, (oldValue, newValue) -> oldValue)) — это скажет стриму оставить старое значение при конфликте.

⚡️ Не перепутайте:
Всегда думайте, возможны ли дубликаты в ваших данных перед использованием toMap().

#java #streamapi #collectors #map #exception #интервью #java_interview_tasks
👍9🤡3❤2
🔍 Ответ на задачу про Stream.findFirst vs findAny: В чём разница? 🔍
- findFirst() жестко привязан к порядку следования (encounter order). В параллельном стриме он потратит время на то, чтобы убедиться, что вернул именно первый элемент.
- findAny() позволяет среде выполнения выбрать любой подходящий элемент. В параллельных стримах это работает гораздо быстрее, так как не нужно координировать потоки для соблюдения порядка.

Вывод:
В параллельном стриме findAny() может вернуть любой элемент, подходящий под условие. Если порядок не важен — используйте его для скорости.

⚡️ Не перепутайте:
В последовательном (sequential) стриме findAny() чаще всего тоже будет возвращать первый элемент, но спецификация этого не гарантирует.

#java #streamapi #parallel #performance #интервью #java_interview_tasks
👍6🔥1
🔍 Ответ на задачу про Stream.flatMap:
- map() превращает каждый элемент в другой элемент (1 -> 1). Если применить его здесь, мы получим стрим стримов: Stream<Stream<String>>.
- flatMap() превращает каждый элемент в стрим, а затем "склеивает" все эти стримы в один плоский Stream<String>.

Вывод:
Вместо двух вложенных списков мы получим один стрим из 3-х символов: "a", "b", "c". Результат count() — 3.

⚡️ Не перепутайте:
Используйте flatMap, когда ваш объект содержит коллекцию или Optional, и вы хотите работать с их содержимым напрямую.

#java #streamapi #flatmap #basics #интервью #java_interview_tasks
🔥2👌1
🔍 Ответ на задачу про Stream.reduce: Опасность identity 🚩
Первый аргумент reduce — это identity. Это значение, которое возвращается, если стрим пуст, и которое используется как начальное при вычислении.
Вычисление идет так: identity + element1 + element2...
В нашем случае: 10 + 1 + 2 + 3 = 16.

Вывод:
Напечатается 16. Если вы хотите просто сумму — identity должен быть 0. Если произведение — 1.

⚡️ Не перепутайте:
Identity должен быть нейтральным элементом для вашей операции. Для сложения это 0, для умножения 1, для конкатенации строк — пустая строка.

#java #streamapi #reduce #basics #интервью #java_interview_tasks
👍5❤1👌1