Java stream collect примеры

Java stream collect примеры

Большинство операций класса Stream, которые модифицируют набор данных, возвращают этот набор в виде потока. Однако бывают ситуации, когда хотелось бы получить данные не в виде потока, а в виде обычной коллекции, например, ArrayList или HashSet. И для этого у класса Stream определен метод collect . Первая версия метода принимает в качестве параметра функцию преобразования к коллекции:

 R collect(Collector collector)

Параметр R представляет тип результата метода, параметр Т — тип элемента в потоке, а параметр А — тип промежуточных накапливаемых данных. В итоге параметр collector представляет функцию преобразования потока в коллекцию.

Эта функция представляет объект Collector, который определен в пакете java.util.stream. Мы можем написать свою реализацию функции, однако Java уже предоставляет ряд встроенных функций, определенных в классе Collectors :

  • toList() : преобразование к типу List
  • toSet() : преобразование к типу Set
  • toMap() : преобразование к типу Map

Например, преобразуем набор в потоке в список:

import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; public class Program < public static void main(String[] args) < Listphones = new ArrayList(); Collections.addAll(phones, "iPhone 8", "HTC U12", "Huawei Nexus 6P", "Samsung Galaxy S9", "LG G6", "Xiaomi MI6", "ASUS Zenfone 2", "Sony Xperia Z5", "Meizu Pro 6", "Lenovo S850"); List filteredPhones = phones.stream() .filter(s->s.length() <10) .collect(Collectors.toList()); for(String s : filteredPhones)< System.out.println(s); >> >

Использование метода toSet() аналогично.

Set filteredPhones = phones.stream() .filter(s->s.length()<10) .collect(Collectors.toSet());

Для применения метода toMap() надо задать ключ и значение. Например, пусть у нас есть следующая модель:

class Phone < private String name; private int price; public Phone(String name, int price)< this.name=name; this.price=price; >public String getName() < return name; >public int getPrice() < return price; >>

Теперь применим метод toMap() :

import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; public class Program < public static void main(String[] args) < StreamphoneStream = Stream.of(new Phone("iPhone 8", 54000), new Phone("Nokia 9", 45000), new Phone("Samsung Galaxy S9", 40000), new Phone("LG G6", 32000)); Map phones = phoneStream .collect(Collectors.toMap(p->p.getName(), t->t.getPrice())); phones.forEach((k,v)->System.out.println(k + " " + v)); > > class Phone < private String name; private int price; public Phone(String name, int price)< this.name=name; this.price=price; >public String getName() < return name; >public int getPrice() < return price; >>

Лямбда-выражение p->p.getName() получает значение для ключа элемента, а t->t.getPrice() - извлекает значение элемента.

Если нам надо создать какой-то определенный тип коллекции, например, HashSet, то мы можем использовать специальные функции, которые определены в классах-коллекций. Например, получим объект HashSet:

import java.util.HashSet; import java.util.stream.Collectors; import java.util.stream.Stream; public class Program < public static void main(String[] args) < Streamphones = Stream.of("iPhone 8", "HTC U12", "Huawei Nexus 6P", "Samsung Galaxy S9", "LG G6", "Xiaomi MI6", "ASUS Zenfone 2", "Sony Xperia Z5", "Meizu Pro 6", "Lenovo S850"); HashSet filteredPhones = phones.filter(s->s.length()<12). collect(Collectors.toCollection(HashSet::new)); filteredPhones.forEach(s->System.out.println(s)); > >

Выражение HashSet::new представляет функцию создания коллекции. Аналогичным образом можно получать другие коллекции, например, ArrayList:

ArrayList result = phones.collect(Collectors.toCollection(ArrayList::new));

Вторая форма метода collect имеет три параметра:

 R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)
  • supplier : создает объект коллекции
  • accumulator : добавляет элемент в коллекцию
  • combiner : бинарная функция, которая объединяет два объекта

Применим эту версию метода collect:

import java.util.ArrayList; import java.util.stream.Collectors; import java.util.stream.Stream; public class Program < public static void main(String[] args) < Streamphones = Stream.of("iPhone 8", "HTC U12", "Huawei Nexus 6P", "Samsung Galaxy S9", "LG G6", "Xiaomi MI6", "ASUS Zenfone 2", "Sony Xperia Z5", "Meizu Pro 6", "Lenovo S850"); ArrayList filteredPhones = phones.filter(s->s.length()<12) .collect( ()->new ArrayList(), // создаем ArrayList (list, item)->list.add(item), // добавляем в список элемент (list1, list2)-> list1.addAll(list2)); // добавляем в список другой список filteredPhones.forEach(s->System.out.println(s)); > >

Источник

Java Stream collect() Method Examples

Java Stream collect() Method Examples

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Java Stream collect() performs a mutable reduction operation on the elements of the stream. This is a terminal operation.

What is Mutable Reduction Operation?

A mutable reduction operation process the stream elements and then accumulate it into a mutable result container. Once the elements are processed, a combining function merges all the result containers to create the result.

Java Stream collect() Method Signature

  1. R collect(Supplier supplier, BiConsumer accumulator,BiConsumer combiner)
  2. R collect(Collector collector)

The Collector is an interface that provides a wrapper for the supplier, accumulator, and combiner objects. The second method is useful when we are utilizing the Collectors class to provide built-in Collector implementation. The three parameters of the collect() function are:

  1. supplier: a function that creates a new mutable result container. For the parallel execution, this function may be called multiple times and it must return a fresh value each time.
  2. accumulator is a stateless function that must fold an element into a result container.
  3. combiner is a stateless function that accepts two partial result containers and merges them, which must be compatible with the accumulator function.

Stream collect() Method Examples

Let’s look at some examples of Stream.collect() method.

1. Concatenating List of Strings

Let’s say you want to concatenate the list of strings to create a new string. We can use Stream collect() function to perform a mutable reduction operation and concatenate the list elements.

List vowels = List.of("a", "e", "i", "o", "u"); // sequential stream - nothing to combine StringBuilder result = vowels.stream().collect(StringBuilder::new, (x, y) -> x.append(y), (a, b) -> a.append(",").append(b)); System.out.println(result.toString()); // parallel stream - combiner is combining partial results StringBuilder result1 = vowels.parallelStream().collect(StringBuilder::new, (x, y) -> x.append(y), (a, b) -> a.append(",").append(b)); System.out.println(result1.toString()); 
  • The supplier function is returning a new StringBuilder object in every call.
  • The accumulator function is appending the list string element to the StringBuilder instance.
  • The combiner function is merging the StringBuilder instances. The instances are merged with each other with a comma between them.
  • In the first case, we have a sequential stream of elements. So they are processed one by one and there is only one instance of StringBuilder. There is no use of the combiner function. That’s why the output produced is “aeiou”.
  • In the second case, we have a parallel stream of strings. So, the elements are processed parallelly and there are multiple instances of StringBuilder that are being merged by the combiner function. Hence, the output produced is “a,e,i,o,u”.
  • If the stream source is ordered such as List, the collect() method maintains the order while processing. If the stream source is unordered such as Set, then the collect() method can produce different results in each invocation.

If you want to concatenate the list of strings, we can use the method references to reduce the code size.

String result2 = vowels.parallelStream() .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) .toString(); 

2. Stream collect() to List using Collectors Class

The Collectors class provides many useful implementations of the Collector interface. Let’s look at an example where we will filter the list of integers to select only even integers. Stream filter() is an intermediate operation and returns a stream. So, we will use the collect() function to create the list from this stream.

List numbers = List.of(1, 2, 3, 4, 5, 6); List evenNumbers = numbers.stream().filter(x -> x % 2 == 0).collect(Collectors.toList()); System.out.println(evenNumbers); // [2, 4, 6] 

The Collectors.toList() returns a Collector implementation that accumulates the input elements into a new List.

3. Stream collect() to a Set

We can use Collectors.toSet() to collect the stream elements into a new Set.

List numbers = List.of(1, 2, 3, 4, 5, 6); Set oddNumbers = numbers.parallelStream().filter(x -> x % 2 != 0).collect(Collectors.toSet()); System.out.println(oddNumbers); // [1, 3, 5] 

3. Stream collect() to Map

We can use Collectors.toMap() function to collect the stream elements to a Map. This method accepts two arguments for mapping key and the corresponding value in the Map.

List numbers = List.of(1, 2, 3, 4, 5, 6); Map mapOddNumbers = numbers.parallelStream().filter(x -> x % 2 != 0) .collect(Collectors.toMap(Function.identity(), x -> String.valueOf(x))); System.out.println(mapOddNumbers); //

4. Collectors joining() Example

We can use Collectors joining() methods to get a Collector that concatenates the input stream CharSequence elements in the encounter order. We can use this to concatenate a stream of strings, StringBuffer, or StringBuilder.

jshell> String value = Stream.of("a", "b", "c").collect(Collectors.joining()); value ==> "abc" jshell> String valueCSV = Stream.of("a", "b", "c").collect(Collectors.joining(",")); valueCSV ==> "a,b,c" jshell> String valueCSVLikeArray = Stream.of("a", "b", "c").collect(Collectors.joining(",", "")); valueCSVLikeArray ==> "" jshell> String valueObject = Stream.of("1", new StringBuffer("2"), new StringBuilder("3")).collect(Collectors.joining()); valueObject ==> "123" 

Java Stream Collect Example

Conclusion

Java Stream collect() is mostly used to collect the stream elements to a collection. It’s a terminal operation. It takes care of synchronization when used with a parallel stream. The Collectors class provides a lot of Collector implementation to help us out.

References

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Источник

Читайте также:  Multiple textbox in html
Оцените статью