Рубрики
Без рубрики

Поток Java 8 – Поток Java

Поток Java 8. Пример учебника Java Stream API. java.util.stream, сокращение потока Java, отображение, сбор, сортировка, плоская карта, фильтр, для каждого, совпадение, поиск

Автор оригинала: Pankaj Kumar.

Добро пожаловать в учебник Java 8 Stream API. В последних нескольких сообщениях Java 8 мы рассмотрели Изменения интерфейса Java 8 и Функциональные интерфейсы и Лямбда-выражения . Сегодня мы рассмотрим один из основных API, представленных в Java 8 – Java Stream .

Поток Java 8

  1. Поток Java 8
  2. Коллекции и поток Java
  3. Функциональные интерфейсы в потоке Java 8
    1. Функция и бифункциональность
    2. Предикат и Предикат
    3. Потребитель и Потребитель
    4. Поставщик
  4. Поставщик
  5. Поставщик
  6. Промежуточные и терминальные операции Java-потока
  7. Операции короткого замыкания потока Java
  8. Примеры потоков Java
    1. Создание потоков Java
    2. Преобразование потока Java в коллекцию или массив
    3. Промежуточные операции потока Java
    4. Терминальные Операции Java-потока
  9. Ограничения API потока Java 8

Поток Java

Прежде чем мы рассмотрим примеры API Java Stream, давайте посмотрим, почему это было необходимо. Предположим, мы хотим перебрать список целых чисел и найти сумму всех целых чисел, превышающих 10.

До Java 8 подход для этого был бы:

private static int sumIterator(List list) {
	Iterator it = list.iterator();
	int sum = 0;
	while (it.hasNext()) {
		int num = it.next();
		if (num > 10) {
			sum += num;
		}
	}
	return sum;
}

С вышеуказанным подходом связаны три основные проблемы:

  1. Мы просто хотим знать сумму целых чисел, но нам также нужно будет указать, как будет проходить итерация, это также называется внешней итерацией , потому что клиентская программа обрабатывает алгоритм для итерации по списку.
  2. Программа носит последовательный характер, мы не можем легко сделать это параллельно.
  3. Существует много кода для выполнения даже простой задачи.

Чтобы преодолеть все вышеперечисленные недостатки, был представлен Java 8 Stream API. Мы можем использовать Java Stream API для реализации внутренней итерации , что лучше, потому что java framework контролирует итерацию.

Внутренняя итерация предоставляет несколько функций, таких как последовательное и параллельное выполнение, фильтрация на основе заданных критериев, сопоставление и т.д.

Большинство аргументов метода API потока Java 8 являются функциональными интерфейсами, поэтому лямбда-выражения очень хорошо работают с ними. Давайте посмотрим, как мы можем записать приведенную выше логику в однострочном операторе, используя потоки Java.

private static int sumStream(List list) {
	return list.stream().filter(i -> i > 10).mapToInt(i -> i).sum();
}

Обратите внимание, что вышеуказанная программа использует стратегию итерации java framework, методы фильтрации и сопоставления и повысит эффективность.

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

Коллекции и поток Java

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

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

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

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

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

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

Все интерфейсы и классы Java Stream API находятся в пакете java.util.stream . Поскольку мы можем использовать примитивные типы данных, такие как int, long, в коллекциях с использованием автоматической упаковки, и эти операции могут занять много времени, существуют специальные классы для примитивных типов- IntStream , LongStream и DoubleStream .

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

Некоторые из часто используемых функциональных интерфейсов в методах API потока Java 8 являются:

  1. Функция и функция Bi : Функция представляет функцию, которая принимает один тип аргумента и возвращает другой тип аргумента. Функция R> – это общая форма, где T-тип входных данных функции, а R-тип результата функции. R>

    – это общая форма, где T-тип входных данных функции, а R-тип результата функции. Для обработки примитивных типов существуют специальные интерфейсы функций – ToIntFunction , ToLongFunction , ToDoubleFunction , ToIntBiFunction , ToLongBiFunction , |/ToDoubleBiFunction , LongToIntFunction , LongToDoubleFunction , IntToLongFunction , IntToDoubleFunction и т. Д.

    Некоторые из потоковых методов, в которых используется Функция или ее примитивная специализация, являются:

    • Карта потока (Функция супер T, ? расширяет R> картограф) супер T, ? расширяет R> картограф)
    • IntStream mapToInt(функция ToIntFunction super T> mapper) – аналогично для длинного и двойного возврата примитивного конкретного потока. super T> mapper) – аналогично для длинного и двойного возврата примитивного конкретного потока.
    • IntStream flatMapToInt(Функция super T, ? расширяет поток> сопоставитель) – аналогично для длинных и двойных super T, ? расширяет поток> сопоставитель) – аналогично для длинных и двойных
    • A[] toArray(генератор функций []>) []>)
    • U уменьшить(U идентичность, бифункция ? супер T, U> накопитель, двоичный оператор объединитель) ? супер T, U> накопитель, двоичный оператор объединитель)
  2. Предикат и Предикат : Он представляет предикат, против которого проверяются элементы потока. Это используется для фильтрации элементов из потока java. Точно так же , как Функция , существуют примитивные специфические интерфейсы для int, long и double.

    Некоторые из потоковых методов, в которых используются Предикат или Двухпредикатные специализации, являются:

    • Фильтр потока (Предикат предикат super T>) предикат super T>)
    • логическое любое соответствие(Предикат предикат super T>) предикат super T>)
    • логическое соответствие(Предикат предикат super T>) предикат super T>)
    • логическое несоответствие(Предикат предикат super T>) предикат super T>)
  3. Потребитель и Потребитель : Он представляет собой операцию, которая принимает один входной аргумент и не возвращает результата. Его можно использовать для выполнения некоторых действий со всеми элементами потока java.

    Некоторые из потоковых методов Java 8, в которых используются Потребитель , Потребитель или его примитивные интерфейсы специализации, являются:

    • Поток заглянуть(Потребитель супер T> действие) супер T> действие)
    • пусто для каждого(Потребитель супер T> действие) супер T> действие)
    • пусто по порядку(Потребитель супер T> действие) супер T> действие)
  4. Поставщик : Поставщик представляет собой операцию, с помощью которой мы можем генерировать новые значения в потоке. Некоторые из методов в потоке, которые принимают аргумент Поставщик , являются:

    • публичный статический Поток генерировать(Поставщик s)
    • Сбор R(Поставщик поставщик,двоичный потребитель ? супер T> аккумулятор,двоичный потребитель R> объединитель) ? супер T> аккумулятор,двоичный потребитель R> объединитель) R> объединитель)

Сбор R(Поставщик поставщик,двоичный потребитель ? супер T> аккумулятор,двоичный потребитель R> объединитель) ? супер T> аккумулятор,двоичный потребитель R> объединитель) R> объединитель)

Java Необязательно-это объект-контейнер, который может содержать или не содержать ненулевое значение. Если значение присутствует, присутствует() вернет значение true и get() вернет значение. Операции терминала потока возвращают необязательный объект. Некоторые из этих методов являются:

  • Необязательно уменьшить(двоичный оператор накопитель)
  • Необязательно мин(Компаратор супер T> компаратор) супер T> компаратор)
  • Необязательно max(Компаратор супер T> компаратор) супер T> компаратор)
  • Необязательно findFirst()
  • Необязательно найдите любой()

Необязательно найдите любой()

Для поддержки параллельного выполнения в потоковом API Java 8 используется интерфейс Spliterator . Метод Spliterator trySplit возвращает новый разделитель, который управляет подмножеством элементов исходного разделителя.

Промежуточные и терминальные операции Java-потока

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

Java 8 Потоковые операции API, которые возвращают результат или создают побочный эффект. Как только метод терминала вызывается в потоке, он потребляет поток, и после этого мы не можем использовать поток. Терминальные операции являются нетерпеливыми по своей природе, т. Е. Они обрабатывают все элементы в потоке, прежде чем возвращать результат. Обычно используемыми терминальными методами являются forEach , toArray , min , max , findFirst , anyMatch , allMatch и т. Д. Вы можете определить терминальные методы по типу возвращаемого значения, они никогда не вернут поток.

Операции короткого замыкания потока Java

Промежуточная операция называется коротким замыканием, если она может привести к конечному потоку для бесконечного потока. Например, limit() и skip() являются двумя промежуточными операциями короткого замыкания.

Терминальная операция называется коротким замыканием, если она может завершиться за конечное время для бесконечного потока. Например anyMatch , allMatch , Несоответствие , findFirst и найти какие-либо являются операциями короткого замыкания терминала.

Примеры потоков Java

Я рассмотрел почти все важные части потокового API Java 8. Очень интересно использовать эти новые функции API, и давайте посмотрим на это в действии на некоторых примерах потока java.

Создание потоков Java

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

  1. Мы можем использовать Stream.of() для создания потока из данных аналогичного типа. Например, мы можем создать поток целых чисел Java из группы объектов int или Integer.

  2. Мы можем использовать Stream.of() с массивом объектов для возврата потока. Обратите внимание, что он не поддерживает автобоксы, поэтому мы не можем передать массив примитивного типа.

  3. Мы можем использовать Collection stream() для создания последовательного потока и parallelStream() для создания параллельного потока.

  4. Мы можем использовать Stream.generate() и Stream.iterate() методы для создания потока.

  5. Используя методы Arrays.stream() и String.chars () .

Преобразование потока Java в коллекцию или массив Существует несколько способов, с помощью которых мы можем получить коллекцию или массив из потока java.Мы можем использовать метод java Stream collect() для получения списка, карты или набора из потока. Поток<Целое число>.из(1,2,3,4); Список<Целое число>.собирать(Коллекторы.ToList()); System.out.println(IntList);//печать [1, 2, 3, 4] .(1,2,3,4);//поток закрыт, поэтому нам нужно создать его снова Map<Целое число,Целое число>.collect(Collectors.toMap(i -> i, i -> i+10)); System.out.println(IntMap);//печатает,,,} Мы можем использовать метод stream toArray() для создания массива из потока. Поток<Целое число>.of(1,2,3,4); Целое число[].toArray(Целое число[]::новый); System.out.println(Массивы.toString(в массиве));//печатает [1, 2, 3, 4] Промежуточные операции Java-потока. Рассмотрим обычно используемый пример промежуточных операций Java – потока.Пример фильтра потока (): Мы можем использовать метод filter() для проверки элементов потока на наличие условия и создания отфильтрованного списка. Список<Целое число> ArrayList<>(); для(int; i<100; i++) myList.