Файл: Что такое функциональное программирование и где оно применяется.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 25.10.2023

Просмотров: 240

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.


Можно ли конкатенировать стримы? если да то каким методом?

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

Вот пример использования метода `concat()`:

```java

Stream stream1 = Stream.of(1, 2, 3);

Stream stream2 = Stream.of(4, 5, 6);

Stream concatenatedStream = Stream.concat(stream1, stream2);

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

```

В данном примере `stream1` содержит элементы `[1, 2, 3]`, а `stream2` содержит элементы `[4, 5, 6]`. После вызова `Stream.concat(stream1, stream2)`, мы получаем новый стрим `concatenatedStream`, который содержит все элементы обоих исходных стримов. В результате вызова `forEach()` для `concatenatedStream` будут выведены все числа от 1 до 6.

Обратите внимание, что после выполнения операции конкатенации стримы `stream1` и `stream2` больше не могут быть использованы отдельно. Конкатенация создает новый стрим, содержащий все элементы, и дальнейшие операции должны быть выполнены на новом стриме `concatenatedStream`.

Можно ли получить пустой стрим?

Да, можно получить пустой стрим с помощью метода `Stream.empty()`.

Метод `Stream.empty()` создает и возвращает пустой стрим, который не содержит ни одного элемента. Такой стрим может быть полезен, когда вам нужно выполнить операции над стримом, но у вас нет конкретных элементов для обработки.

Вот пример использования `Stream.empty()`:

```java

Stream emptyStream = Stream.empty();

long count = emptyStream.count();

System.out.println(count); // Вывод: 0

```

В данном примере `emptyStream` представляет собой пустой стрим. Мы вызываем метод `count()`, чтобы получить количество элементов в стриме, которое в данном случае будет равно 0.

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

Как получить стрим из массива?

Для получения стрима из массива в Java можно воспользоваться статическим методом `Arrays.stream()`. Этот метод принимает массив в качестве параметра и возвращает стрим, который содержит элементы массива.


Вот пример использования `Arrays.stream()` для получения стрима из массива:

```java

int[] array = {1, 2, 3, 4, 5};

Stream stream = Arrays.stream(array);

```

В этом примере мы создаем массив `array`, содержащий целочисленные значения. Затем мы используем `Arrays.stream(array)` для создания стрима, который содержит элементы этого массива. Теперь мы можем выполнять различные операции над этим стримом, такие как фильтрация, отображение, сортировка и другие.

Аналогично, для получения стрима из других типов массивов (например, `double[]`, `long[]`, `char[]`, и т.д.), можно использовать соответствующую перегруженную версию метода `Arrays.stream()`, принимающую массив соответствующего типа.

Что такое коллекторы?

Коллекторы (Collectors) в Java представляют собой удобный инструмент, который позволяет собирать элементы стрима и выполнять различные агрегатные операции над ними для получения окончательного результата.

Коллекторы используются в сочетании с терминальными операциями стрима, такими как `collect()`, чтобы определить, как элементы стрима должны быть сгруппированы, отфильтрованы, отображены, сведены к одному значению и т.д.

Java предоставляет множество предопределенных коллекторов в классе `Collectors`, которые покрывают широкий спектр задач. Некоторые из наиболее часто используемых коллекторов включают:

- `toList()`: собирает элементы в список.

- `toSet()`: собирает элементы в множество.

- `toMap()`: собирает элементы в карту, используя ключ и значение.

- `joining()`: объединяет элементы в одну строку.

- `summingInt()`, `summingLong()`, `summingDouble()`: вычисляет сумму числовых значений.

- `averagingInt()`, `averagingLong()`, `averagingDouble()`: вычисляет среднее значение числовых значений.

- и другие.

Кроме того, вы также можете определить свои собственные коллекторы, реализовав интерфейс `Collector` и определив методы `supplier`, `accumulator`, `combiner` и `finisher`.

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

Objects (зачем нужен)

Класс `Objects` в Java предоставляет удобные методы для работы с объектами. Он содержит статические методы, которые обеспечивают некоторую функциональность, связанную с объектами, и являются удобными в использовании.



Вот некоторые основные методы, предоставляемые классом `Objects`:

1. `equals(Object a, Object b)`: Позволяет сравнить два объекта на равенство. Этот метод учитывает случаи, когда один или оба объекта могут быть `null`, и обеспечивает корректное выполнение сравнения.

2. `hashCode(Object o)`: Возвращает хэш-код для указанного объекта. Этот метод предоставляет реализацию хэш-кода, которая соответствует реализации метода `equals`. Он также учитывает случай, когда объект является `null`, и возвращает нулевой хэш-код в этом случае.

3. `toString(Object o)`: Возвращает строковое представление указанного объекта. Если объект является `null`, то возвращается строка `"null"`. Если объект не является `null`, то используется его метод `toString()` для получения строки представления.

4. `requireNonNull(T obj)`: Проверяет, что указанный объект не является `null`. Если объект равен `null`, то метод выбрасывает исключение `NullPointerException`. Это полезный метод для проверки аргументов методов или переменных, чтобы избежать нежелательных `null`-значений.


Класс `Objects` обеспечивает удобные методы для обработки объектов, особенно в контексте сравнения, хэширования и строкового представления. Он помогает упростить и обезопасить операции с объектами, предоставляя общепринятую функциональность, которая может быть использована в различных ситуациях.

Метод sorted

Метод `sorted` является промежуточной операцией в Java Stream API и используется для сортировки элементов стрима на основе некоторого критерия. Он возвращает новый стрим, содержащий отсортированные элементы.

Сигнатура метода `sorted`:

```

Stream sorted()

Stream sorted(Comparator super T> comparator)

```

Метод `sorted` без аргументов сортирует элементы стрима в естественном порядке с использованием их естественного порядка сортировки. Это означает, что элементы должны быть сравнимыми (реализовывать интерфейс `Comparable`) и иметь реализацию метода `compareTo`.

Пример использования метода `sorted`:

```java

List numbers = List.of(5, 2, 8, 1, 6, 3);

List sortedNumbers = numbers.stream()

.sorted()

.collect(Collectors.toList());

System.out.println(sortedNumbers); // Вывод: [1, 2, 3, 5, 6, 8]

```

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

Пример использования метода `sorted` с компаратором:

```java

List names = List.of("John", "Alice", "Bob", "David");

List sortedNames = names.stream()

.sorted(Comparator.comparing(String::length))

.collect(Collectors.toList());

System.out.println(sortedNames); // Вывод: [Bob, John, Alice, David]

```

В этом примере элементы списка `names` сортируются по длине строк в порядке возрастания.

Метод `sorted` полезен для упорядочивания элементов стрима перед выполнением других операций или для получения отсортированного результата.

В чем разница Stream и Iterator


Stream и Iterator - это два различных подхода к обработке последовательности элементов, предоставляемых коллекцией или другими источниками данных.

1. Stream:

- Stream является более высокоуровневым и функциональным подходом.

- Stream API предоставляет набор операций для обработки данных, таких как фильтрация, отображение, сортировка и агрегация.

- Операции над стримами обычно выполняются с использованием функциональных интерфейсов и лямбда-выражений.

- Stream не хранит элементы в памяти, а работает с элементами на лету по требованию.

- Стримы могут использовать параллельную обработку для повышения производительности.

- Stream API предоставляет удобные методы для преобразования и агрегации данных.

- Stream может быть неизменяемым и неупорядоченным, что позволяет оптимизировать обработку данных.

2. Iterator:

- Iterator - это более низкоуровневый подход и является частью Java Collections Framework.

- Iterator предоставляет базовые методы для итерации по элементам коллекции, такие как `next()`, `hasNext()` и `remove()`.

- Итераторы работают в императивном стиле и требуют явного контроля над итерацией и состоянием.

- Итераторы могут перемещаться только вперед по коллекции и обычно не поддерживают параллельную обработку.

- Итераторы работают непосредственно с элементами коллекции, поэтому требуют доступа к памяти для хранения элементов.

- Iterator не предоставляет встроенных операций для преобразования и агрегации данных, поскольку его основная задача - обход элементов.

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

Что такое Collector? (это интерфейс).

Интерфейс Collector в Java представляет собой комбинированный механизм для накопления элементов стрима в какую-то коллекцию или другую структуру данных. Он определяет операции для накопления, объединения и завершения накопления элементов стрима.

Collector определяет следующие методы:

1. Supplier supplier(): Возвращает функцию-поставщик, которая создает и возвращает пустой контейнер для накопления элементов.