http://wm-monitoring.ru/ ')) {alert('Спасибо за то что установили нашу кнопку! =)');} else {alert('Очень жаль! =(');}"> http://wm-monitoring.ru/

Java 8 Streams: введение в фильтрацию, сопоставление и сокращение операций

  1. Создание потока
  2. Метод карты
  3. Метод фильтра
  4. Операции сокращения
  5. Заключение

Узнайте больше о Java с нашим учебником Соединение Android и Java в разработке Android на сайте.

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

В этом уроке я собираюсь показать вам, как создавать потоки, а затем преобразовывать их, используя три широко используемых метода более высокого порядка, называемых map, filter и Reduce.

Код для этого поста можно найти Вот ,

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

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

В Java 8 каждый класс, который реализует интерфейс java.util.Collection, имеет метод stream, который позволяет вам преобразовывать его экземпляры в объекты Stream. Следовательно, любой список легко преобразовать в поток. Вот пример, который преобразует ArrayList объектов Integer в поток:

// Создать список ArrayList <Integer> myList = new ArrayList <Integer> (); myList.add (1); myList.add (5); myList.add (8); // Преобразовать его в поток Stream <Integer> myStream = myList.stream ();

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

// Создать массив Integer [] myArray = {1, 5, 8}; // Преобразовать его в поток Stream <Integer> myStream = Arrays.stream (myArray);

Метод карты

Получив объект Stream, вы можете использовать различные методы для его преобразования в другой объект Stream. Первый такой метод, который мы рассмотрим, это метод map. Он принимает лямбда-выражение в качестве единственного аргумента и использует его для изменения каждого отдельного элемента в потоке. Его возвращаемое значение - новый объект Stream, содержащий измененные элементы.

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

Вы начинаете с преобразования массива в поток:

String [] myArray = new String [] {"bob", "alice", "paul", "ellie"}; Stream <String> myStream = Arrays.stream (myArray);

Затем вы вызываете метод map, передавая лямбда-выражение, которое может преобразовать строку в верхний регистр в качестве единственного аргумента:

Stream <String> myNewStream = myStream.map (s -> s.toUpperCase ());

Возвращенный объект Stream содержит измененные строки. Чтобы преобразовать его в массив, вы используете метод toArray:

String [] myNewArray = myNewStream.toArray (String [] :: new);

На данный момент у вас есть массив строк, все из которых в верхнем регистре.

Я надеюсь, что вы сейчас начинаете понимать, что с этим стилем программирования вы можете покончить с циклами, и код, который вы пишете, может быть очень лаконичным и читабельным.

Метод фильтра

В предыдущем разделе вы видели, что метод map обрабатывает каждый элемент в объекте Stream. Возможно, вы не всегда этого хотите. Иногда вам может потребоваться работать только с подмножеством элементов. Для этого вы можете использовать метод фильтра.

Как и метод map, метод filter ожидает лямбда-выражение в качестве аргумента. Однако переданное ему лямбда-выражение всегда должно возвращать логическое значение, которое определяет, должен ли обработанный элемент принадлежать результирующему объекту Stream.

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

Arrays.stream (myArray) .filter (s -> s.length ()> 4) .toArray (String [] :: new);

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

Операции сокращения

Операция сокращения - это операция, которая позволяет вычислить результат, используя все элементы, присутствующие в потоке. Операции сокращения также называются терминальными операциями, потому что они всегда присутствуют в конце цепочки методов Stream. Мы уже использовали метод сокращения в наших предыдущих примерах: метод toArray. Это терминальная операция, потому что она преобразует объект Stream в массив.

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

int myArray [] = {1, 5, 8}; int sum = Arrays.stream (myArray) .sum ();

Однако если вы хотите выполнять более сложные операции сокращения, вы должны использовать метод сокращения. В отличие от методов map и filter, метод Reduce предполагает два аргумента: элемент тождества и лямбда-выражение. Вы можете думать об элементе идентичности как о элементе, который не изменяет результат операции сокращения. Например, если вы пытаетесь найти произведение всех элементов в потоке чисел, элементом идентичности будет номер 1.

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

Ниже приведен пример фрагмента кода, который использует метод Reduce для объединения всех элементов в массиве объектов String:

String [] myArray = {"this", "is", "a", "Предложение"}; String result = Arrays.stream (myArray) .reduce ("", (a, b) -> a + b);

Заключение

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

Я также хотел бы сообщить вам, что если вы предпочитаете не использовать лямбда-выражения при работе с методами map, filter и Reduce, вы всегда можете вместо этого использовать ссылки на методы.

Чтобы узнать больше о Streams API и других методах, которые он может предложить, вы можете обратиться к его документация ,

Узнайте больше о Java с нашим учебником Соединение Android и Java в разработке Android на сайте.

Карта