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

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

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Что выведет код?

import java.util.*;

public class Main {
public static void main(String[] args) {
Set<String> set = new HashSet<>(Arrays.asList("apple", "banana", "cherry", "date"));
set.removeIf(s -> s.length() > 5);
System.out.println(set);
}
}


#Tasks
Выбор очевиден же? 😂

https://t.me/Java_for_beginner_dev

#Mems
Основные утилитные методы класса Collections

1. sort(List<T> list)
Метод sort(List<T> list) сортирует элементы списка в естественном порядке или с использованием заданного компаратора. Это один из самых часто используемых методов для упорядочивания элементов в списке.
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

public class SortExample {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(3);
numbers.add(1);
numbers.add(4);
numbers.add(2);

Collections.sort(numbers);

System.out.println("Sorted list: " + numbers);
}
}


Вывод:
Sorted list: [1, 2, 3, 4]
Этот пример демонстрирует сортировку списка целых чисел в естественном порядке (по возрастанию). Метод sort упорядочивает элементы на месте, изменяя исходный список.


2. reverse(List<?> list)

Метод reverse(List<?> list) изменяет порядок элементов в списке на противоположный. Это полезно, когда необходимо быстро изменить порядок элементов, например, для реализации функции отмены действий или для отображения данных в обратном порядке.
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

public class ReverseExample {
public static void main(String[] args) {
List<String> items = new ArrayList<>();
items.add("Apple");
items.add("Banana");
items.add("Cherry");

Collections.reverse(items);

System.out.println("Reversed list: " + items);
}
}


Вывод:
Reversed list: [Cherry, Banana, Apple]
В этом примере список строк меняет свой порядок на противоположный с помощью метода reverse.


3. shuffle(List<?> list)
Метод shuffle(List<?> list) случайным образом перемешивает элементы списка. Этот метод полезен для создания случайных выборок данных, например, при разработке игр, тестов или при случайном перемешивании колоды карт.
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

public class ShuffleExample {
public static void main(String[] args) {
List<String> items = new ArrayList<>();
items.add("Apple");
items.add("Banana");
items.add("Cherry");

Collections.shuffle(items);

System.out.println("Shuffled list: " + items);
}
}


Вывод может быть таким:
Shuffled list: [Banana, Cherry, Apple]
Метод shuffle перемешивает элементы списка в случайном порядке, так что каждый вызов метода может давать разный результат.


4. binarySearch(List<? extends Comparable<? super T>> list, T key)
Метод binarySearch(List<? extends Comparable<? super T>> list, T key) выполняет двоичный поиск указанного элемента в отсортированном списке. Метод возвращает индекс элемента, если он найден, и отрицательное значение, если элемент отсутствует в списке.
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

public class BinarySearchExample {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
numbers.add(5);

int index = Collections.binarySearch(numbers, 3);

if (index >= 0) {
System.out.println("Found at index: " + index);
} else {
System.out.println("Not found");
}
}
}


Вывод:
Found at index: 2
Этот пример демонстрирует использование двоичного поиска для поиска числа 3 в отсортированном списке чисел.


#Java #Training #Medium #Collections
5. max(Collection<? extends T> coll)
Метод max(Collection<? extends T> coll) находит максимальный элемент в коллекции, используя естественный порядок или заданный компаратор. Этот метод полезен для нахождения наибольшего значения в наборе данных.
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

public class MaxExample {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(3);
numbers.add(1);
numbers.add(4);
numbers.add(2);

int maxNumber = Collections.max(numbers);

System.out.println("Max number: " + maxNumber);
}
}


Вывод:
Max number: 4
В этом примере метод max находит наибольшее число в списке чисел.


6. min(Collection<? extends T> coll)
Метод min(Collection<? extends T> coll) находит минимальный элемент в коллекции, используя естественный порядок или заданный компаратор. Этот метод часто используется вместе с max для определения диапазона значений в наборе данных.
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

public class MinExample {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(3);
numbers.add(1);
numbers.add(4);
numbers.add(2);

int minNumber = Collections.min(numbers);

System.out.println("Min number: " + minNumber);
}
}


Вывод:

Min number: 1
Метод min определяет минимальное значение в списке чисел.


7. frequency(Collection<?> c, Object o)
Метод frequency(Collection<?> c, Object o) возвращает количество раз, которое объект o встречается в коллекции c. Этот метод полезен для анализа данных и подсчета количества повторений элемента в коллекции.
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

public class FrequencyExample {
public static void main(String[] args) {
List<String> items = new ArrayList<>();
items.add("Apple");
items.add("Banana");
items.add("Apple");
items.add("Cherry");
items.add("Apple");

int appleCount = Collections.frequency(items, "Apple");

System.out.println("Frequency of 'Apple': " + appleCount);
}
}


Вывод:
Frequency of 'Apple': 3
Этот пример показывает, как с помощью метода frequency можно подсчитать количество раз, когда слово "Apple" встречается в списке.


8. fill(List<? super T> list, T obj)
Метод fill(List<? super T> list, T obj) заменяет все элементы списка одним и тем же значением. Это полезно, когда требуется инициализировать или сбросить все элементы списка до одного значения.
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

public class FillExample {
public static void main(String[] args) {
List<String> items = new ArrayList<>(Collections.nCopies(5, ""));
Collections.fill(items, "Apple");

System.out.println("Filled list: " + items);
}
}


Вывод:
Filled list: [Apple, Apple, Apple, Apple, Apple]
Этот код заменяет все элементы в списке на строку "Apple" с помощью метода fill.


#Java #Training #Medium #Collections
Arrays, особенности и внутреннее устройство

Массивы (Arrays) в Java являются одной из самых фундаментальных структур данных, широко используемых при разработке программного обеспечения. Они предоставляют простой способ хранения множества однотипных элементов в единой структуре, обеспечивая доступ к каждому элементу по индексу.


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

Внутреннее устройство массивов

Массивы в Java представляют собой последовательные блоки памяти, выделенные для хранения элементов одного типа. Каждый элемент массива хранится в определенной ячейке памяти, и все элементы идут друг за другом. Такой способ хранения позволяет обеспечить доступ к элементам за константное время O(1).


Пример создания массива:
public class ArrayExample {
public static void main(String[] args) {
// Создание массива целых чисел длиной 5
int[] numbers = new int[5];

// Инициализация массива
numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;
numbers[3] = 40;
numbers[4] = 50;

// Вывод элементов массива
for (int i = 0; i < numbers.length; i++) {
System.out.println("Element at index " + i + ": " + numbers[i]);
}
}
}


Вывод:
Element at index 0: 10
Element at index 1: 20
Element at index 2: 30
Element at index 3: 40
Element at index 4: 50
В этом примере создается массив целых чисел длиной 5 и инициализируется значениями. Доступ к каждому элементу осуществляется через индекс.


Особенности массивов

1. Фиксированный размер
Одной из ключевых особенностей массивов является их фиксированный размер. После создания массива его размер не может быть изменен, что ограничивает его гибкость. Если требуется изменить размер массива, необходимо создать новый массив и скопировать в него данные из старого.

2. Однородность данных
Массивы могут хранить только данные одного типа. Например, если вы создаете массив целых чисел, вы не можете поместить в него строку или другой тип данных. Это ограничение обеспечивает высокую производительность, поскольку Java точно знает, сколько памяти выделить для каждого элемента массива.

3. Быстрый доступ к элементам
Преимуществом массивов является быстрый доступ к любому элементу по индексу. Этот доступ осуществляется за константное время O(1), что делает массивы эффективными для задач, где требуется частый доступ к элементам по их позиции.

4. Ограниченная функциональность
В отличие от коллекций, массивы не поддерживают методы для добавления, удаления или сортировки элементов. Все операции с массивами, такие как поиск или сортировка, необходимо реализовывать вручную или с использованием утилитных классов, таких как Arrays в Java.

Типы массивов

1. Одномерные массивы
Одномерный массив — это наиболее простой тип массива, в котором элементы хранятся в одном измерении, то есть в виде списка.
public class OneDimensionalArray {
public static void main(String[] args) {
int[] numbers = {10, 20, 30, 40, 50};

for (int i = 0; i < numbers.length; i++) {
System.out.println("Element at index " + i + ": " + numbers[i]);
}
}
}


#Java #Training #Medium #Arrays
2. Многомерные массивы
Многомерный массив — это массив массивов. Наиболее часто используется двумерный массив, который можно представить как таблицу, где строки и столбцы содержат данные.
public class TwoDimensionalArray {
public static void main(String[] args) {
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};

for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.println("Element at [" + i + "][" + j + "]: " + matrix[i][j]);
}
}
}
}



Вывод:
Element at [0][0]: 1
Element at [0][1]: 2
Element at [0][2]: 3
Element at [1][0]: 4
Element at [1][1]: 5
Element at [1][2]: 6
Element at [2][0]: 7
Element at [2][1]: 8
Element at [2][2]: 9


3. Разреженные массивы

Разреженные массивы — это разновидность многомерных массивов, где каждая строка может иметь разное количество столбцов. Это полезно, когда разные строки массива могут иметь различное количество данных.
public class JaggedArray {
public static void main(String[] args) {
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[]{1, 2};
jaggedArray[1] = new int[]{3, 4, 5};
jaggedArray[2] = new int[]{6, 7, 8, 9};

for (int i = 0; i < jaggedArray.length; i++) {
for (int j = 0; j < jaggedArray[i].length; j++) {
System.out.println("Element at [" + i + "][" + j + "]: " + jaggedArray[i][j]);
}
}
}
}


Вывод:
Element at [0][0]: 1
Element at [0][1]: 2
Element at [1][0]: 3
Element at [1][1]: 4
Element at [1][2]: 5
Element at [2][0]: 6
Element at [2][1]: 7
Element at [2][2]: 8
Element at [2][3]: 9


Преимущества и недостатки массивов

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


Недостатки
Фиксированный размер: Главным недостатком массивов является их фиксированный размер. Если требуется изменить количество элементов, необходимо создавать новый массив и копировать данные из старого.
Отсутствие гибкости: Массивы не поддерживают динамические операции, такие как добавление или удаление элементов, что делает их менее гибкими по сравнению с коллекциями.
Неудобство при работе с разнородными данными: Массивы могут хранить только элементы одного типа, что ограничивает их использование в задачах, где требуется хранить данные различных типов.

#Java #Training #Medium #Arrays
Что выведет код?

import java.util.Arrays;

public class Main {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
int[] subArr = Arrays.copyOfRange(arr, 1, 4);
subArr[0] = 10;
System.out.println(Arrays.toString(subArr));
System.out.println(Arrays.toString(arr));
}
}


#Tasks
А какая Алиса будет дальше?🤨

https://t.me/Java_for_beginner_dev

#Mems
Основные утилитные методы класса Arrays

1. Arrays.toString()
Метод toString() преобразует массив в строковое представление, что удобно для вывода его содержимого в лог или консоль. Этот метод поддерживает массивы любых типов, включая примитивные типы и объекты.
import java.util.Arrays;

public class ToStringExample {
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
String arrayAsString = Arrays.toString(numbers);
System.out.println("Array: " + arrayAsString);
}
}


Вывод:
Array: [1, 2, 3, 4, 5]


2. Arrays.sort()
Метод sort() сортирует массив по возрастанию с использованием алгоритма быстрой сортировки (QuickSort) для примитивных типов и сортировки слиянием (MergeSort) для объектов. Этот метод чрезвычайно полезен для упорядочивания данных.
import java.util.Arrays;

public class SortExample {
public static void main(String[] args) {
String[] fruits = {"Banana", "Apple", "Cherry", "Date"};
Arrays.sort(fruits);
System.out.println("Sorted array: " + Arrays.toString(fruits));
}
}


Вывод:
Sorted array: [Apple, Banana, Cherry, Date]


3. Arrays.binarySearch()
Метод binarySearch() используется для поиска элемента в отсортированном массиве. Если элемент найден, метод возвращает его индекс; если нет — отрицательное значение, указывающее на предполагаемую позицию элемента в массиве.
import java.util.Arrays;

public class BinarySearchExample {
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
int index = Arrays.binarySearch(numbers, 3);
if (index >= 0) {
System.out.println("Element found at index: " + index);
} else {
System.out.println("Element not found");
}
}
}


Вывод:

Element found at index: 2


4. Arrays.copyOf()
Метод copyOf() позволяет создать копию массива с новым размером. Этот метод полезен для изменения размера массива или создания его дубликата.
import java.util.Arrays;

public class CopyOfExample {
public static void main(String[] args) {
int[] original = {1, 2, 3};
int[] copy = Arrays.copyOf(original, 5);
System.out.println("Original array: " + Arrays.toString(original));
System.out.println("Copied array: " + Arrays.toString(copy));
}
}


Вывод:
Original array: [1, 2, 3]
Copied array: [1, 2, 3, 0, 0]
В этом примере новый массив copy содержит те же элементы, что и original, но его длина увеличена до 5. Остальные элементы заполняются значениями по умолчанию для типа данных (в данном случае нулями для целых чисел).


5. Arrays.equals()
Метод equals() проверяет, равны ли два массива по содержимому. Этот метод полезен при необходимости сравнения массивов, так как оператор == проверяет только равенство ссылок, а не содержимого массивов.
import java.util.Arrays;

public class EqualsExample {
public static void main(String[] args) {
int[] array1 = {1, 2, 3};
int[] array2 = {1, 2, 3};
boolean areEqual = Arrays.equals(array1, array2);
System.out.println("Arrays are equal: " + areEqual);
}
}


Вывод:
Arrays are equal: true


#Java #Training #Medium #Arrays
Сложные методы класса Arrays

1. Arrays.parallelSort()
Метод parallelSort() сортирует массив, используя многопоточность для повышения производительности на многоядерных процессорах. Этот метод особенно полезен для сортировки больших массивов, где использование параллелизма может значительно ускорить процесс.
import java.util.Arrays;

public class ParallelSortExample {
public static void main(String[] args) {
int[] largeArray = {5, 1, 4, 2, 3};
Arrays.parallelSort(largeArray);
System.out.println("Parallel sorted array: " + Arrays.toString(largeArray));
}
}


Вывод:
Parallel sorted array: [1, 2, 3, 4, 5]


2. Arrays.stream()
Метод stream() позволяет преобразовать массив в поток (Stream), что открывает доступ к богатому набору методов для обработки данных, таких как фильтрация, маппинг и редукция. Этот метод особенно полезен для выполнения сложных операций над массивами в функциональном стиле.
import java.util.Arrays;
import java.util.stream.IntStream;

public class StreamExample {
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
IntStream stream = Arrays.stream(numbers);
int sum = stream.filter(n -> n % 2 == 0).sum();
System.out.println("Sum of even numbers: " + sum);
}
}


Вывод:
Sum of even numbers: 6
В этом примере метод stream() преобразует массив в поток, который затем используется для фильтрации четных чисел и их суммирования.


3. Arrays.deepEquals()

Метод deepEquals() сравнивает вложенные массивы (например, двумерные массивы), обеспечивая корректное сравнение их содержимого. Это важно, так как обычный метод equals() сравнивает ссылки на вложенные массивы, а не их содержимое.
import java.util.Arrays;

public class DeepEqualsExample {
public static void main(String[] args) {
int[][] array1 = {{1, 2, 3}, {4, 5, 6}};
int[][] array2 = {{1, 2, 3}, {4, 5, 6}};
boolean areEqual = Arrays.deepEquals(array1, array2);
System.out.println("2D arrays are equal: " + areEqual);
}
}


Вывод:
2D arrays are equal: true


4. Arrays.setAll()
Метод setAll() позволяет инициализировать или модифицировать массив, применяя к каждому элементу функцию на основе его индекса. Этот метод особенно удобен для создания последовательностей или для сложных инициализаций массива.
import java.util.Arrays;

public class SetAllExample {
public static void main(String[] args) {
int[] numbers = new int[5];
Arrays.setAll(numbers, i -> i * 2);
System.out.println("Array after setAll: " + Arrays.toString(numbers));
}
}


Вывод:
Array after setAll: [0, 2, 4, 6, 8]


#Java #Training #Medium #Arrays
Stream API, внутреннее устройство, особенности и преимущества

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

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

Основные характеристики Stream API:

Декларативный стиль: Позволяет писать код в функциональном стиле, описывая, что нужно сделать, а не как это сделать.
Ленивые вычисления: Операции на потоках выполняются только тогда, когда это действительно необходимо.
Неизменяемость: Потоки не изменяют исходные данные, а создают новые потоки или результаты.
Поддержка параллелизма: Stream API легко интегрируется с параллельными вычислениями, что позволяет улучшить производительность на многоядерных процессорах.


Внутреннее устройство Stream API

Stream API реализован на основе концепции потоков данных (streams), которые представляют собой последовательности элементов из источника данных, такого как коллекция, массив или I/O. Потоки могут быть конечными и бесконечными, что позволяет работать как с ограниченными, так и с неограниченными последовательностями данных.

1. Источник данных
Потоки создаются из различных источников данных, таких как коллекции (List, Set, Map), массивы или генераторы данных. Например, можно создать поток из списка с использованием метода stream():
import java.util.Arrays;
import java.util.List;

public class StreamCreationExample {
public static void main(String[] args) {
List<String> items = Arrays.asList("apple", "banana", "orange");
items.stream().forEach(System.out::println);
}
}
В этом примере создается поток из списка строк и выводится каждый элемент на консоль.


2. Операции над потоками
Stream API поддерживает два типа операций: промежуточные (intermediate) и терминальные (terminal).

Промежуточные операции: Они применяются к потоку и возвращают новый поток. Примеры: filter(), map(), sorted(). Эти операции ленивы, что означает, что они не выполняются до тех пор, пока не будет вызвана терминальная операция.


Терминальные операции: Эти операции приводят к завершению работы с потоком, производя результат или побочные эффекты. Примеры: collect(), forEach(), reduce().

#Java #Training #Medium #StreamAPI
3. Ленивые вычисления
Одной из ключевых особенностей Stream API является ленивость вычислений. Это означает, что промежуточные операции на потоке не выполняются сразу, а откладываются до тех пор, пока не будет вызвана терминальная операция. Благодаря этому достигается высокая производительность, так как обрабатывается только необходимое количество данных.

4. Параллельные потоки

Stream API предоставляет возможность легко параллелизировать потоковые операции. Это достигается с помощью метода parallelStream(), который разделяет поток на несколько частей, которые обрабатываются параллельно на разных ядрах процессора.
import java.util.Arrays;
import java.util.List;

public class ParallelStreamExample {
public static void main(String[] args) {
List<String> items = Arrays.asList("apple", "banana", "cherry", "date");

items.parallelStream()
.map(String::toUpperCase)
.forEach(System.out::println);
}
}
В этом примере элементы списка обрабатываются параллельно, что может привести к ускорению выполнения, особенно при работе с большими объемами данных.


Особенности Stream API

1. Неизменяемость
Потоки в Java неизменяемы, что означает, что исходные данные никогда не изменяются. Вместо этого создаются новые потоки или результаты на основе исходных данных. Это делает код более безопасным и предсказуемым, устраняя возможность случайных изменений данных.

2. Ленивость
Как уже упоминалось, ленивые вычисления — это важная особенность Stream API, которая позволяет значительно повысить производительность, особенно при работе с большими объемами данных. Потоковые операции выполняются только тогда, когда это необходимо, что позволяет избежать ненужных вычислений.

3. Параллелизм
Stream API легко интегрируется с параллельными вычислениями, что позволяет более эффективно использовать возможности многоядерных процессоров. Использование параллельных потоков (parallelStream) позволяет обрабатывать данные параллельно, улучшая производительность в многопоточных средах.

Преимущества Stream API

1. Читаемость кода
Stream API значительно улучшает читаемость и лаконичность кода. Вместо использования циклов и условных операторов, разработчики могут использовать потоковые операции, чтобы выразить свою логику декларативно.
import java.util.Arrays;
import java.util.List;

public class ClassicVsStreamExample {
public static void main(String[] args) {
List<String> items = Arrays.asList("apple", "banana", "cherry", "date");

// Классический подход
for (String item : items) {
if (item.startsWith("a")) {
System.out.println(item.toUpperCase());
}
}

// Подход с использованием Stream API
items.stream()
.filter(item -> item.startsWith("a"))
.map(String::toUpperCase)
.forEach(System.out::println);
}
}
Вывод обоих подходов будет одинаковым, но код с использованием Stream API выглядит более лаконично и понятно.


2. Эффективность
Stream API позволяет обрабатывать данные более эффективно благодаря ленивым вычислениям и поддержке параллелизма. Это особенно важно при работе с большими коллекциями данных, где производительность играет ключевую роль.

3. Легкость параллелизации
Stream API предоставляет простую и интуитивно понятную возможность параллелизации обработки данных. Использование метода parallelStream() не требует сложной настройки многопоточности, что делает параллельные вычисления доступными даже для менее опытных разработчиков.

4. Функциональный подход
Stream API позволяет использовать функциональный стиль программирования, который становится все более популярным. Это позволяет писать код, который более выразителен и легче тестируется, а также способствует лучшей поддержке и масштабируемости.


#Java #Training #Medium #StreamAPI
Варианты ответа:
Anonymous Quiz
0%
5
0%
8
36%
4
64%
3
Что выведет код?

import java.util.Arrays;
import java.util.List;

public class Main {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(3, 7, 8, 10, 15, 18);
long count = numbers.stream()
.filter(n -> n % 3 == 0)
.map(n -> n * 2)
.count();
System.out.println(count);
}
}


#Tasks
А кто поступает по другому? 😜

https://t.me/Java_for_beginner_dev

#Mems
Основные методы Stream API и примеры использования

1. filter()
Метод filter() используется для фильтрации элементов потока на основе заданного условия. Он принимает предикат (функцию, возвращающую boolean), и если элемент удовлетворяет этому условию, он остается в потоке.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FilterExample {
public static void main(String[] args) {
List<String>```java
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FilterExample {
public static void main(String[] args) {
List<String> items = Arrays.asList("apple", "banana", "cherry", "date");

List<String> filteredItems = items.stream()
.filter(item -> item.startsWith("a"))
.collect(Collectors.toList());

System.out.println("Filtered items: " + filteredItems);
}
}
В этом примере фильтруются только те элементы списка, которые начинаются с буквы "a". Результат собирается в новый список с помощью метода collect() и выводится на консоль.


2. map()
Метод map() используется для преобразования элементов потока. Он принимает функцию, которая применяется к каждому элементу потока, и возвращает новый поток с преобразованными элементами.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class MapExample {
public static void main(String[] args) {
List<String> items = Arrays.asList("apple", "banana", "cherry", "date");

List<String> upperCaseItems = items.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());

System.out.println("Uppercase items: " + upperCaseItems);
}
}
В этом примере все строки из списка преобразуются в верхний регистр, и результат снова собирается в новый список.


3. flatMap()
Метод flatMap() используется для преобразования потоков из элементов, которые сами являются потоками. Этот метод "раскрывает" вложенные потоки, объединяя их в один поток.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FlatMapExample {
public static void main(String[] args) {
List<List<String>> listOfLists = Arrays.asList(
Arrays.asList("apple", "banana"),
Arrays.asList("cherry", "date")
);

List<String> flatList = listOfLists.stream()
.flatMap(List::stream)
.collect(Collectors.toList());

System.out.println("Flattened list: " + flatList);
}
}
В этом примере два списка объединяются в один с помощью flatMap(), и результат собирается в новый список.


4. collect()

Метод collect() используется для сбора элементов потока в коллекцию или для других операций агрегирования. Чаще всего используется с Collectors, чтобы собрать элементы в список, множество или другую коллекцию.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class CollectExample {
public static void main(String[] args) {
List<String> items = Arrays.asList("apple", "banana", "cherry", "date");

List<String> collectedItems = items.stream()
.collect(Collectors.toList());

System.out.println("Collected items: " + collectedItems);
}
}


#Java #Training #Medium #StreamAPI
5. reduce()
Метод reduce() используется для агрегирования всех элементов потока в одно значение. Этот метод принимает бинарную операцию, которая сворачивает элементы потока до одного результата.
import java.util.Arrays;
import java.util.List;

public class ReduceExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

int sum = numbers.stream()
.reduce(0, Integer::sum);

System.out.println("Sum: " + sum);
}
}
В этом примере все числа в списке суммируются, и результат выводится на консоль.


6. forEach()
Метод forEach() выполняет действие для каждого элемента потока. Это терминальная операция, которая завершает работу потока, не возвращая результата.
import java.util.Arrays;
import java.util.List;

public class ForEachExample {
public static void main(String[] args) {
List<String> items = Arrays.asList("apple", "banana", "cherry", "date");

items.stream().forEach(System.out::println);
}
}


7. distinct()
Метод distinct() используется для удаления дубликатов из потока. Он возвращает поток, содержащий только уникальные элементы.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class DistinctExample {
public static void main(String[] args) {
List<String> items = Arrays.asList("apple", "banana", "apple", "date");

List<String> distinctItems = items.stream()
.distinct()
.collect(Collectors.toList());

System.out.println("Distinct items: " + distinctItems);
}
}


8. sorted()
Метод sorted() используется для сортировки элементов потока. Он может принимать компаратор, если требуется нестандартная сортировка.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class SortedExample {
public static void main(String[] args) {
List<String> items = Arrays.asList("banana", "apple", "date", "cherry");

List<String> sortedItems = items.stream()
.sorted()
.collect(Collectors.toList());

System.out.println("Sorted items: " + sortedItems);
}
}


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

1. Подсчет количества уникальных слов в тексте
Предположим, у нас есть текст, и мы хотим узнать, сколько уникальных слов в нем содержится.
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;

public class UniqueWordsExample {
public static void main(String[] args) {
String text = "apple banana apple cherry date cherry banana";

Set<String> uniqueWords = Arrays.stream(text.split(" "))
.collect(Collectors.toSet());

System.out.println("Unique words: " + uniqueWords);
System.out.println("Number of unique words: " + uniqueWords.size());
}
}


Вывод:
Unique words: [banana, date, cherry, apple]
Number of unique words: 4


#Java #Training #Medium #StreamAPI
2. Фильтрация и преобразование списка объектов
Рассмотрим пример, где у нас есть список объектов Person, и мы хотим отфильтровать людей старше 18 лет, а затем преобразовать их имена в верхний регистр.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class Person {
private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}
}

public class PersonExample {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 23),
new Person("Bob", 17),
new Person("Charlie", 19)
);

List<String> adultsNames = people.stream()
.filter(person -> person.getAge() > 18)
.map(Person::getName)
.map(String::toUpperCase)
.collect(Collectors.toList());

System.out.println("Adults' names: " + adultsNames);
}
}


Вывод:
Adults' names: [ALICE, CHARLIE]


3. Группировка объектов по ключу
Допустим, нам нужно сгруппировать людей по возрасту.
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class Person {
private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}
}

public class GroupingByExample {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", 23),
new Person("Bob", 17),
new Person("Charlie", 23),
new Person("David", 17)
);

Map<Integer, List<Person>> groupedByAge = people.stream()
.collect(Collectors.groupingBy(Person```java
.collect(Collectors.groupingBy(Person::getAge)));

groupedByAge.forEach((age, personList) -> {
System.out.println("Age: " + age);
personList.forEach(person -> System.out.println(" " + person.getName()));
});
}
}
В этом примере люди группируются по возрасту, и результат выводится на консоль. Группировка позволяет удобно структурировать данные по ключевому признаку, что полезно в задачах аналитики и отчетности.


Вывод:
Age: 17
Bob
David
Age: 23
Alice
Charlie


#Java #Training #Medium #StreamAPI