Java | Фишки и трюки
7.21K subscribers
182 photos
29 videos
6 files
40 links
Java: примеры кода, интересные фишки и полезные трюки

Купить рекламу: https://telega.in/c/java_tips_and_tricks

✍️По всем вопросам: @Pascal4eg
Download Telegram
⌨️ Полезные стримы. Поиск максимального

Дан список людей с именем и возрастом. Нужно найти самого старшего.
import java.util.Comparator;
import java.util.List;

record Person(String name, int age) {}

public class StreamExample {
public static void main(String[] args) {
List<Person> people = List.of(
new Person("Alice", 30),
new Person("Bob", 20),
new Person("Charlie", 40)
);

people.stream()
.max(Comparator.comparingInt(Person::age))
.ifPresent(person -> System.out.println("Oldest person: " + person.name()));
// Вывод: Oldest person: Charlie
}
}

#java #stream #max
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥19👍43
⌨️ Полезные стримы. Группировка

Дан список людей с именем и городом проживания. Нужно сгруппировать их по городам.

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

record Person(String name, String city) {}

public class StreamExample {
public static void main(String[] args) {
List<Person> people = List.of(
new Person("Alice", "New York"),
new Person("Bob", "Los Angeles"),
new Person("Charlie", "New York"),
new Person("David", "Los Angeles"),
new Person("Edward", "San Francisco")
);

Map<String, List<Person>> peopleByCity = people.stream()
.collect(Collectors.groupingBy(Person::city));

peopleByCity.forEach((city, peopleInCity) -> {
System.out.println(city + ": " + peopleInCity.stream()
.map(Person::name)
.collect(Collectors.joining(", ")));
});
// Вывод:
// San Francisco: Edward
// New York: Alice, Charlie
// Los Angeles: Bob, David
}
}


#java #stream #grouping
Please open Telegram to view this post
VIEW IN TELEGRAM
👍23🔥4👏21
⌨️ Полезные стримы. Объединение стримов

Даны два списка фруктов. Нужно объединить их в одном стриме, обработать его и вывести результат.


var list1 = List.of("apple", "banana", "cherry");
var list2 = List.of("orange", "pineapple", "mango");

var result = Stream.concat(list1.stream(), list2.stream())
.filter(s -> s.length() > 5)
.toList();

System.out.println(result);
// [banana, cherry, orange, pineapple]


#java #stream #concat
Please open Telegram to view this post
VIEW IN TELEGRAM
👍23🔥21👏1
⌨️ Полезные стримы. Метод distinct()

Если у вас есть поток, который может содержать повторяющиеся элементы, используйте операцию distinct(), чтобы удалить их.


var list = Arrays.asList(1, 2, 3, 3, 4, 5, 5);
var distinctList = list.stream()
.distinct()
.collect(Collectors.toList());
// distinctList: [1, 2, 3, 4, 5]


#java #stream #distinct
Please open Telegram to view this post
VIEW IN TELEGRAM
👍23🔥21👏1
⌨️ Полезные стримы. Сортировка

Отсортировать список с помощью стрима можно используя метод sorted():

var list = List.of(10, 5, 7, 3);
var sortedList = list.stream()
.sorted()
.toList();
sortedList.forEach(System.out::println);
// 3 5 7 10


Можно передать Comparator:

var list = List.of(10, 5, 7, 3);
var sortedList = list.stream()
.sorted(Comparator.reverseOrder())
.toList();
sortedList.forEach(System.out::println);
// 10 7 5 3


#java #stream #sorted
Please open Telegram to view this post
VIEW IN TELEGRAM
👍81🔥1
⌨️ Полезные стримы. Метод peek()

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

Это промежуточная операция.

Для конвейеров параллельных потоков действие может быть вызвано в любое время и в любом потоке, в котором элемент становится доступным в результате вышестоящей операции. Если действие изменяет общее состояние, оно отвечает за обеспечение необходимой синхронизации.

Этот метод существует в основном для отладки, когда вы хотите видеть элементы по мере их прохождения через определенную точку конвейера:

Stream.of("one", "two", "three", "four")
.filter(e -> e. length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
// Filtered value: three
// Mapped value: THREE
// Filtered value: four
// Mapped value: FOUR


В тех случаях, когда реализация потока может оптимизировать создание некоторых или всех элементов (например findFirst или count), действие не будет вызываться для этих элементов.

#java #stream #peek
Please open Telegram to view this post
VIEW IN TELEGRAM
👍121
⌨️ Срезы в стримах. Метод takeWhile

В Java 9 появилось два новых метода, полезных для выбора элементов потока с хорошей производительностью: takeWhile и dropWhile.

Допустим, у нас есть следующий список блюд:

List<Dish> specialMenu = Arrays.asList(
new Dish("seasonal fruit", 120),
new Dish("prawns", 300),
new Dish("rice", 350),
new Dish("chicken", 400),
new Dish("french fries", 530));


Для получения блюд с калорийностью меньше 320, можно воспользоваться операцией filter. Недостаток операции filter в том, что она требует прохода в цикле по всему потоку данных с применением предиката ко всем элементам.

В нашем примере список уже отсортирован по числу калорий. Вместо того, чтобы пройтись по каждому элементу, можно прекратить работу сразу же после обнаружения блюда, содержащего 320 калорий или более. В случае небольшого списка это может показаться не таким уж громадным преимуществом, но при работе с потенциально большим потоком элементов окажется весьма полезным.

Поможет нам в этом операция takeWhile! Она позволяет выполнить срез любого потока данных (даже бесконечного) с помощью предиката. И, к счастью, она прекращает работу сразу же по обнаружении неподходящего элемента. Вот как ее следует использовать:

List<Dish> sliceMenu1
= specialMenu.stream()
.takeWhile(dish -> dish.getCalories() < 320)
.collect(toList());


#java #stream #takeWhile
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍23🤝21🔥1🤔1
⌨️ Срезы в стримах. Метод dropWhile

Операция dropWhile служит дополнением к операции takeWhile. Она отбрасывает первые элементы, для которых предикат возвращает true. Как только результат вычисления предиката становится ложным, она прекращает работу и возвращает все оставшиеся элементы, причем работает даже в том случае, если число оставшихся элементов бесконечно!


List<Integer> ints = List.of(1,2,3,4,5,6,7,8,9);
ints.stream()
.dropWhile(i -> i < 5)
.forEach(System.out::println);
// 5 6 7 8 9


#java #stream #dropWhile
Please open Telegram to view this post
VIEW IN TELEGRAM
👍183
⌨️ Усечение потока данных. Метод limit

Потоки данных поддерживают метод limit(n). Он возвращает еще один поток, не превышающий заданную длину, переданную в limit в виде аргумента. Если поток данных упорядоченный, возвращаются первые элементы, но не более чем n.

Например, с помощью следующего кода можно создать List, выбрав первые три блюда, содержащие более 300 калорий:

List<Dish> dishes = specialMenu
.stream()
.filter(dish -> dish.getCalories() > 300)
.limit(3)
.collect(toList());


Метод limit работает и для неупорядоченных потоков данных (например, когда источник представляет собой объект типа Set). В этом случае не следует исходить из допущения о какой-либо упорядоченности результата, возвращенного методом limit.

#java #stream #limit
Please open Telegram to view this post
VIEW IN TELEGRAM
🤝3👍2
⌨️ "Распрямление" потока. Метод flatMap

Метод Stream.flatMap используется для преобразования элементов одного потока (stream) в несколько элементов другого потока, а затем объединения этих элементов в один поток. Это особенно полезно, когда у вас есть коллекция коллекций, и вы хотите "распрямить" её, т.е. получить плоскую структуру, содержащую все элементы.

Допустим, у вас есть список строк, каждая из которых содержит несколько слов, и вы хотите получить поток всех слов:

List<String> sentences = Arrays.asList("Java is fun", "I love programming");

Stream<String> wordsStream = sentences.stream()
.flatMap(sentence -> Arrays.stream(sentence.split(" "))); // Преобразуем в поток слов

wordsStream.forEach(System.out::println);


Результат:

Java
is
fun
I
love
programming


Здесь каждый массив слов был преобразован в поток, а затем flatMap "распрямил" эти потоки в один.

#java #stream #flatMap
Please open Telegram to view this post
VIEW IN TELEGRAM
👍81
⌨️ Чем отличаются методы Stream.toList() и Stream.collect(Collectors.toList())?

Методы Stream.toList() и Stream.collect(Collectors.toList()) кажутся схожими, так как оба возвращают список, но есть ключевое отличие: Stream.toList() возвращает неизменяемый список, а Stream.collect(Collectors.toList()) возвращает изменяемый список на базе ArrayList.

#java #stream #toList
Please open Telegram to view this post
VIEW IN TELEGRAM
👍203