Java 8 - Примеры Stream.map ()

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

Вступление

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

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

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

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

Типы потоков

Потоки могут быть последовательными (создаваемыми с помощью stream() ) или параллельными (создаваемыми с помощью parallelStream() ). Параллельные потоки могут работать с несколькими потоками, а последовательные - нет.

Операции над потоками могут быть как промежуточными, так и терминальными :

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

  • map(op) - возвращает новый поток, в котором предоставленная op применяется к каждому из элементов в исходном потоке.
  • filter(cond) - возвращает новый поток, который содержит только элементы из исходного потока, которые удовлетворяют условию cond , заданному предикатом
  • sorted() - возвращает исходный поток, но с сортируемыми элементами

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

Некоторые из операций терминала:

  • collect() - возвращает результат промежуточных операций, выполненных с исходным потоком.
  • forEach() - метод void, используемый для итерации по потоку
  • reduce() - возвращает единственный результат, полученный из всей последовательности элементов в исходном потоке

В этом руководстве мы рассмотрим map() и то, как мы можем использовать ее с потоками для преобразования / сопоставления объектов различных типов.

Stream.map () Примеры

Давайте рассмотрим пару примеров и посмотрим, что мы можем сделать с помощью операции map()

Поток целых чисел в поток строк

 Arrays.asList(1, 2, 3, 4).stream() 
 .map(n -> "Number " + String.valueOf(n)) 
 .forEach(n -> System.out.println(n + " as a " + n.getClass().getName())); 

Здесь мы составили список целых чисел и вызвали в нем stream() чтобы создать новый поток данных. Затем мы сопоставили каждое число n в списке с помощью map() со строкой. Строки просто состоят из "Number" и String.valueOf(n) .

Итак, для каждого числа в нашем исходном списке теперь у нас будет соответствующая ему строка "Number n"

Поскольку map() снова возвращает Stream , мы использовали метод forEach() для печати каждого элемента в нем.

Выполнение этого кода приводит к:

 Number 1 as a java.lang.String 
 Number 2 as a java.lang.String 
 Number 3 as a java.lang.String 
 Number 4 as a java.lang.String 

Примечание: это нисколько не изменило исходный список. Мы просто обработали данные и распечатали результаты. Если бы мы хотели сохранить это изменение, мы бы collect() данные обратно в Collection такой как List , Map , Set и т. Д.:

 List<Integer> list = Arrays.asList(1, 2, 3, 4); 
 
 List<String> mappedList = list.stream() 
 .map(n -> "Number " + String.valueOf(n)) 
 .collect(Collectors.toList()); 
 
 System.out.println(list); 
 System.out.println(mappedList); 

Это приводит к:

 [1, 2, 3, 4] 
 [Number 1, Number 2, Number 3, Number 4] 

Поток строк в поток целых чисел

Теперь давайте сделаем наоборот - преобразуем поток строк в поток целых чисел:

 Arrays.asList("1", "2", "3", "4").stream() 
 .map(n -> Integer.parseInt(n)) 
 .forEach(n -> System.out.println(n)); 

Как и ожидалось, этот код выдаст следующий результат:

 1 
 2 
 3 
 4 

Список объектов в списке других объектов

Допустим, у нас есть класс Point который представляет одну точку в декартовой системе координат:

 public class Point { 
 int X; 
 int Y; 
 
 Point(int x, int y){ 
 this.X=x; 
 this.Y=y; 
 } 
 
 @Override 
 public String toString() { 
 return "(" + this.X + ", " + this.Y + ")"; 
 } 
 
 } 

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

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

 List<Point> originalPoints = Arrays.asList(new Point(1, 2), 
 new Point(3, 4), 
 new Point(5, 6), 
 new Point(7, 8)); 
 System.out.println("Original vertices: " + originalPoints); 
 
 List<Point> scaledPoints = originalPoints 
 .stream() 
 .map(n -> new Point(nX * 2, nY * 2)) 
 .collect(Collectors.toList()); 
 
 System.out.println("Scaled vertices: " + scaledPoints); 

В этом примере будет получен следующий результат:

 Original vertices: [(1, 2), (3, 4), (5, 6), (7, 8)] 
 Scaled vertices: [(2, 4), (6, 8), (10, 12), (14, 16)] 

Заключение

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

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

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus