Java for Beginner
675 subscribers
558 photos
156 videos
12 files
851 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Введение в Stream API и основные методы создания стримов

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

Создание стримов

Из коллекций:
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();


Из массивов:
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);


Из значений:

Stream<String> stream = Stream.of("a", "b", "c");


Из файлов:
try (Stream<String> stream = Files.lines(Paths.get("file.txt"))) {
stream.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}


Бесконечные стримы:

iterate:
Stream<Integer> stream = Stream.iterate(0, n -> n + 2).limit(10);
stream.forEach(System.out::println);


generate:
Stream<Double> stream = Stream.generate(Math::random).limit(10);
stream.forEach(System.out::println);



Промежуточные методы Stream API

Промежуточные методы возвращают новый стрим, позволяя строить цепочки операций.


filter:
List<String> list = Arrays.asList("a", "ab", "abc", "abcd");
list.stream()
.filter(s -> s.length() > 2)
.forEach(System.out::println); // abc, abcd


map:
List<String> list = Arrays.asList("1", "2", "3");
list.stream()
.map(Integer::parseInt)
.forEach(System.out::println); // 1, 2, 3


flatMap:
List<List<String>> list = Arrays.asList(
Arrays.asList("a", "b"),
Arrays.asList("c", "d")
);
list.stream()
.flatMap(Collection::stream)
.forEach(System.out::println); // a, b, c, d


distinct:
List<String> list = Arrays.asList("a", "b", "a", "c", "b");
list.stream()
.distinct()
.forEach(System.out::println); // a, b, c


sorted:

Без компаратора:
List<String> list = Arrays.asList("c", "a", "b");
list.stream()
.sorted()
.forEach(System.out::println); // a, b, c


С компаратором:
List<String> list = Arrays.asList("c", "a", "b");
list.stream()
.sorted(Comparator.reverseOrder())
.forEach(System.out::println); // c, b, a


peek:
List<String> list = Arrays.asList("a", "b", "c");
list.stream()
.peek(System.out::println)
.map(String::toUpperCase)
.forEach(System.out::println); // a, A, b, B, c, C


limit:
Stream<Integer> stream = Stream.iterate(1, n -> n + 1);
stream.limit(5)
.forEach(System.out::println); // 1, 2, 3, 4, 5


skip:
Stream<Integer> stream = Stream.iterate(1, n -> n + 1);
stream.skip(5)
.limit(5)
.forEach(System.out::println); // 6, 7, 8, 9, 10


#Java #Training #Stream #Medium
Терминальные методы Stream API

Терминальные методы завершают цепочку операций со стримами, возвращая результат или выполняя действие.

forEach:
List<String> list = Arrays.asList("a", "b", "c");
list.stream()
.forEach(System.out::println); // a, b, c


collect:
List<String> list = Arrays.asList("a", "b", "c");
List<String> result = list.stream()
.collect(Collectors.toList());


reduce:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int sum = list.stream()
.reduce(0, (a, b) -> a + b);


toArray:
List<String> list = Arrays.asList("a", "b", "c");
String[] array = list.stream()
.toArray(String[]::new);


findFirst:
List<String> list = Arrays.asList("a", "b", "c");
Optional<String> first = list.stream()
.findFirst();


findAny:
List<String> list = Arrays.asList("a", "b", "c");
Optional<String> any = list.stream()
.findAny();


count:
List<String> list = Arrays.asList("a", "b", "c");
long count = list.stream()
.count();


anyMatch:
List<String> list = Arrays.asList("a", "b", "c");
boolean anyMatch = list.stream()
.anyMatch(s -> s.equals("a"));


allMatch:
List<String> list = Arrays.asList("a", "b", "c");
boolean allMatch = list.stream()
.allMatch(s -> s.length() == 1);


noneMatch:
List<String> list = Arrays.asList("a", "b", "c");
boolean noneMatch = list.stream()
.noneMatch(s -> s.equals("d"));



Продвинутые методы и примеры использования Stream API

groupingBy:
List<String> list = Arrays.asList("a", "ab", "abc", "abcd");
Map<Integer, List<String>> groupedByLength = list.stream()
.collect(Collectors.groupingBy(String::length));


partitioningBy:
List<String> list = Arrays.asList("a", "ab", "abc", "abcd");
Map<Boolean, List<String>> partitionedByLength = list.stream()
.collect(Collectors.partitioningBy(s -> s.length() > 2));


mapping:
List<String> list = Arrays.asList("a", "ab", "abc", "abcd");
List<Integer> lengths = list.stream()
.collect(Collectors.mapping(String::length, Collectors.toList()));


joining:
List<String> list = Arrays.asList("a", "b", "c");
String joined = list.stream()
.collect(Collectors.joining(", "));


Примеры использования Stream API

Фильтрация и преобразование списка строк:
List<String> list = Arrays.asList("apple", "banana", "cherry", "date");
List<String> result = list.stream()
.filter(s -> s.startsWith("a"))
.map(String::toUpperCase)
.collect(Collectors.toList());


Группировка чисел по четности:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Map<Boolean, List<Integer>> evenOddMap = numbers.stream()
.collect(Collectors.partitioningBy(n -> n % 2 == 0));


Подсчет элементов в списке:
List<String> list = Arrays.asList("a", "b", "c", "a", "b", "c");
Map<String, Long> frequencyMap = list.stream()
.collect(Collectors.groupingBy(s -> s, Collectors.counting()));


Нахождение максимального значения в списке:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> maxNumber = numbers.stream()
.max(Integer::compare);


#Java #Training #Stream #Medium
Поддержка функционального программирования в Java

Начиная с Java 8, язык получил мощные инструменты для поддержки функционального программирования:

Лямбда-выражения: Позволяют писать анонимные функции в компактной форме.
Функциональные интерфейсы: Интерфейсы с одним абстрактным методом (SAM), которые могут быть реализованы с помощью лямбда-выражений.
Stream API: Позволяет работать с коллекциями в функциональном стиле.

Лямбда-выражения

Лямбда-выражения — это краткий способ написания анонимных функций.

Они состоят из:
Списка параметров.
Стрелки (->).
Тела функции.


Синтаксис:
(параметры) -> { тело функции }


Примеры:

Простое лямбда-выражение:
// Без лямбды
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Hello, World!");
}
};

// С лямбдой
Runnable runnable = () -> System.out.println("Hello, World!");


Лямбда с параметрами:
// Без лямбды
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return a.compareTo(b);
}
};

// С лямбдой
Comparator<Integer> comparator = (a, b) -> a.compareTo(b);


Лямбда с несколькими строками:
// Без лямбды
Function<String, Integer> lengthFunction = new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return s.length();
}
};

// С лямбдой
Function<String, Integer> lengthFunction = s -> {
System.out.println("Calculating length of: " + s);
return s.length();
};


Преимущества лямбда-выражений
Упрощение кода.
Улучшение читаемости.
Поддержка функционального стиля программирования.


Недостатки лямбда-выражений
Могут быть сложны для понимания новичкам.
Отладка лямбда-выражений может быть менее удобной.


Функциональные интерфейсы

Функциональные интерфейсы — это интерфейсы, которые содержат ровно один абстрактный метод (Single Abstract Method, SAM). Они используются для представления лямбда-выражений и ссылок на методы.

Примеры функциональных интерфейсов в Java:
Predicate<T>: Принимает один аргумент и возвращает boolean.
Function<T, R>: Принимает один аргумент и возвращает результат.
Consumer<T>: Принимает один аргумент и не возвращает результат.
Supplier<T>: Не принимает аргументов, но возвращает результат.


Пример использования:
// Predicate
Predicate<Integer> isEven = n -> n % 2 == 0;
System.out.println(isEven.test(4)); // true

// Function
Function<String, Integer> lengthFunction = String::length;
System.out.println(lengthFunction.apply("Hello")); // 5

// Consumer
Consumer<String> printConsumer = System.out::println;
printConsumer.accept("Hello, World!");

// Supplier
Supplier<Double> randomSupplier = Math::random;
System.out.println(randomSupplier.get()); // Случайное число


#Java #Training #Medium #Functional_programming #Stream_API #Lambda_expressions #Functional_interfaces
Stream API

Stream API — это мощный инструмент для работы с коллекциями в функциональном стиле. Он позволяет выполнять операции над данными, такие как фильтрация, преобразование, сортировка и агрегация, без изменения исходных данных.

Основные операции Stream API:
Промежуточные операции (intermediate): Возвращают новый поток и могут быть объединены в цепочку.
filter(Predicate<T>): Фильтрует элементы.
map(Function<T, R>): Преобразует элементы.
sorted(): Сортирует элементы.
Терминальные операции (terminal): Завершают поток и возвращают результат.
forEach(Consumer<T>): Выполняет действие для каждого элемента.
collect(Collector<T, A, R>): Собирает элементы в коллекцию.
reduce(BinaryOperator<T>): Сворачивает элементы в одно значение.


Пример использования:
List<String> languages = List.of("Java", "Kotlin", "Scala", "Groovy");

// Фильтрация и преобразование
List<String> filteredLanguages = languages.stream()
.filter(lang -> lang.startsWith("J")) // Фильтруем по условию
.map(String::toUpperCase) // Преобразуем в верхний регистр
.collect(Collectors.toList()); // Собираем в список

System.out.println(filteredLanguages); // [JAVA]

// Агрегация
int totalLength = languages.stream()
.mapToInt(String::length) // Преобразуем в длины строк
.sum(); // Суммируем длины

System.out.println(totalLength); // 18



Преимущества
Stream API
Упрощение работы с коллекциями.
Поддержка параллельного выполнения (через parallelStream()).
Читаемость и выразительность кода.


Недостатки Stream API
Может быть менее производительным для простых операций из-за накладных расходов.
Сложность отладки из-за цепочек вызовов.


#Java #Training #Medium #Functional_programming #Stream_API #Lambda_expressions #Functional_interfaces