Учебное пособие по Java 8 Streams с примерами кода

В этом сообщении блога мы собираемся обсудить возможности Java 8 Streams и предоставить множество различных примеров кода.

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



Зачем использовать потоки Java?

Некоторые из преимуществ потоков:


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


Трубопровод потоков

В большинстве случаев конвейер потоков состоит из

  • источник (откуда исходят ваши данные)
  • за которым следует ноль или более промежуточные операции
  • и один терминальная операция

Потоки Java - фильтр, карта, уменьшение


Источник будет передавать поток элементов.

Этот поток элементов можно фильтровать, сортировать, отображать или применять к каждому элементу другие серии операций.

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

Источник потока

Источник потока могут поступать из коллекций, списков, наборов, массивов int, long, double, strings и т. д.


Потоковые операции

Потоковые операции являются либо промежуточными, либо конечными:

  • Промежуточные операции такие как filter, map или sort, возвращают поток, чтобы мы могли связать несколько промежуточных операций.
  • Терминальные операции получают поток, и они могут либо вернуть void, либо они могут вернуть результат, отличный от потока, такой как сокращение, например уменьшить элементы до списка.

Промежуточные операции

  • Допускается ноль или более промежуточных операций.
  • Порядок имеет значение; для больших наборов данных: сначала фильтровать затем отсортируйте или сопоставьте.
  • Для очень больших наборов данных используется ParallelStream для включения нескольких потоков.

Некоторые из промежуточных операций включают:

  • anyMatch ()
  • отчетливый()
  • фильтр()
  • findFirst ()
  • плоская карта ()
  • карта()
  • пропускать()
  • отсортировано ()

Терминальные операции

Разрешена только одна терминальная операция.

  • forEach применяет одну и ту же функцию к каждому элементу, например, печатает каждый элемент.
  • collect сохраняет все элементы в коллекцию, список или массив.
  • все остальные параметры сокращают поток до одного итогового элемента.

Вот некоторые примеры функций сокращения:


  • считать()
  • Максимум()
  • мин ()
  • уменьшать()


Примеры кода Java Streams

Теперь давайте посмотрим на приведенные выше концепции в примерах кода.

Целочисленный поток

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

forEach это наша терминальная операция. По каждому пункту мы просто распечатаем его.

import java.io.IOException; import java.util.stream.IntStream; public class JavaStreams {
public static void main(String[] args) throws IOException {
IntStream

.range(1, 10)

.forEach(System.out::print);
System.out.println();
} }

Выход:


123456789

Целочисленный поток с пропуском

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

Это будут только элементы с 6 по 9. Мы также используем простое лямбда-выражение для печати элемента.

import java.io.IOException; import java.util.stream.IntStream; public class JavaStreams {
public static void main(String[] args) throws IOException {
IntStream

.range(1, 10)

.skip(5)

.forEach(x -> System.out.println(x));
System.out.println();
} }

Выход:

6 7 8 9

Целочисленный поток с суммой

В третьем примере мы снова используем IntStream однако для создания нашего потока объектов мы помещаем его внутри println() оператор в качестве параметра для строки печати.


То, что мы собираемся напечатать, - это просто сумма от 1 до 5, другими словами, 1, 2, 3 и 4, будет распечатана только сумма этих чисел:

import java.io.IOException; import java.util.stream.IntStream; public class JavaStreams {
public static void main(String[] args) throws IOException {
System.out.println(
IntStream

.range(1, 5)

.sum());
System.out.println();
} }

Выход:

10

Stream.of

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

В этом примере мы просто собираемся выполнить прямую сортировку по алфавиту, а затем найдем первый элемент с помощью findFirst() функция. Затем мы просто распечатываем первый элемент в списке.

import java.io.IOException; import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream.of('Ava', 'Aneri', 'Alberto')

.sorted()

.findFirst()

.ifPresent(System.out::println);
} }

Выход

Alberto

Поток из массива, сортировка, фильтрация и печать

В нашем следующем примере мы собираемся выполнять потоковую передачу из массива. Затем мы собираемся отсортировать, отфильтровать и распечатать.

Здесь мы собираемся отфильтровать только те элементы, которые начинаются с s.

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

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

import java.io.IOException; import java.util.Arrays; public class JavaStreams {
public static void main(String[] args) throws IOException {
String[] names = {'Al', 'Ankit', 'Kushal', 'Brent', 'Sarika', 'amanda', 'Hans', 'Shivika', 'Sarah'};
Arrays.stream(names)


.filter(x -> x.startsWith('S'))


.sorted()


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

Выход:

Sarah Sarika Shivika

Среднее значение целочисленного массива

Теперь давайте посмотрим, как мы можем взять среднее значение квадратов массива int.

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

import java.util.Arrays; public class JavaStreams {
public static void main(String[] args) {
Arrays.stream(new int[] {2, 4, 6, 8, 10})


.map(x -> x * x)


.average()


.ifPresent(System.out::println);
} }

Выход:

44.0

Обратите внимание, что он печатает двойное вместо целого числа.

Поток из списка, фильтрация и печать

В этом примере мы собираемся выполнить потоковую передачу из списка, отфильтровать эти элементы и затем распечатать.

Обратите внимание, что внутри map() функции, мы собираемся преобразовать все имена в нижний регистр.

import java.util.Arrays; import java.util.List; public class JavaStreams {
public static void main(String[] args) {
List people = Arrays.asList('Al', 'Ankit', 'Brent', 'Sarika', 'amanda', 'Hans', 'Shivika', 'Sarah');
people


.stream()


.map(String::toLowerCase)


.filter(x -> x.startsWith('a'))


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

Выход:

al ankit amanda

Мы видим, что у нас есть три имени, которые начинаются с a и все они в нижнем регистре.

Потоковая передача строк из текстового файла, сортировка, фильтрация и печать

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

Предположим, у нас есть файл с именем bands.txt с содержанием, показанным ниже:

Rolling Stones Lady Gaga Jackson Browne Maroon 5 Arijit Singh Elton John John Mayer CCR Eagles Pink Aerosmith Adele Taylor Swift

Мы собираемся использовать Files.lines() чтобы создать наш поток, который даст нам поток строки для каждой строки файла.

Когда у нас есть поток, мы собираемся отсортировать их, отфильтровать элементы, длина которых превышает 13 символов, а затем распечатать оставшиеся элементы.

Наконец, мы должны закрыть файл, поэтому мы делаем bands.close.

import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream bands = Files.lines(Paths.get('bands.txt'));
bands


.sorted()


.filter(x -> x.length() > 13)


.forEach(System.out::println);
bands.close();
} }

Выход:

Jackson Browne Rolling Stones

Получаем две группы, в которых больше 13 символов.

Потоковая передача строк из текстового файла и сохранение в списке

В этом примере мы будем использовать тот же текстовый файл, что и выше.

Мы хотим отфильтровать элементы, содержащие буквы jit, используя x.contains() это просто строковая функция.

Использование .collect() складываем все с буквами jit в список.

Когда у нас есть список, мы можем использовать forEach оператор для печати элементов.

import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; import java.util.stream.Collectors; public class JavaStreams {
public static void main(String[] args) throws IOException {
List bands2 = Files.lines(Paths.get('bands.txt'))


.filter(x -> x.contains('jit'))


.collect(Collectors.toList());
bands2.forEach(x -> System.out.println(x));
} }

Выход:

Arijit Singh

Строки потоковой передачи из файла CSV и подсчет

В этом примере мы транслируем строки из файла CSV и собираемся подсчитать хорошие строки.

Предположим, у нас есть файл с именем data.txt со следующим содержанием:

A,12,3.7 B,17,2.8 C,14,1.9 D,23,2.7 E F,18,3.4

Здесь строка E не имеет данных, поэтому мы хотим исключить ее из нашего потока.

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

Затем мы применяем фильтр, чтобы отфильтровать строки, в которых нет трех элементов.

import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream rows1 = Files.lines(Paths.get('data.txt'));
int rowCount = (int)rows1


.map(x -> x.split(','))


.filter(x -> x.length == 3)


.count();
System.out.println(rowCount + ' rows.');
rows1.close();
} }

Выход:

5 rows

Снижение - сумма

В этом примере показано, как использовать сокращение. Мы собираемся сократить до суммы. Здесь у нас есть двойной поток, использующий Stream.of() функция. Мы определили три двойных числа в трех разных аргументах и ​​собираемся использовать функцию сокращения.

import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) {
double total = Stream.of(7.3, 1.5, 4.8)


.reduce(0.0, (Double a, Double b) -> a + b);
System.out.println('Total = ' + total);
} }

Выход:

13.600000000000001