Pages

Friday, December 10, 2021

Java 8 Stream Collect() Examples

1. Overview

In this tutorial, We will learn how to use the Stream.collect() method in Java 8 Stream api.

Many of you know that Stream.collect() method is added as part of the new JDK 8 Streams.

Stream collect() method is used to collect the output of stream operations into the collection such as List, Set or Map. Sometimes we can collect into LinkedList, TreeSet or even into the String.

Additionally, we can perform the group by, partition by operations on the streams with Collect() method.

Let us explore the usages of Stream.collect() method with examples.

Java 8 Stream Collect() Examples



2. Java 8 Stream Collect() to List using Collectors.toList()


The below is the first example using Stream.collect() method on the stream pipe line. First created a stream object using stream() method and converted the each value in the stream to uppercase using word.toUpperCase() method. 

Finally, called the collect() method by passing the Collectors.toList() method which collect the each word from the stream into a List. The returned list is the instance of ArrayList and it is the default collection object created by toList() method.


package com.javaprogramto.java8.collectors.collect;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Examples to Java 8 Stream collect() method
 * 
 * @author JavaProgramTo.com
 *
 */
public class StreamCollectExample {

	public static void main(String[] args) {

		List<String> words = Arrays.asList("hello", "how", "are", "you", "doing", "mate");
		
		List<String> list = words.stream()
				.map(word -> word.toUpperCase())
				.collect(Collectors.toList());
		
		System.out.println("Collectors.toList() : "+list);

	}

}
 
Output:
Collectors.toList() : [HELLO, HOW, ARE, YOU, DOING, MATE]
 

3. Java 8 Stream Collect() to Set using Collectors.toSet()


Furthermore, The below example is to get the numbers length is 3 and remove the duplicates from stream. Finally, collecting the stream output into Set.

And also collected the same output into the List to observe the difference between the toList() and toSet() methods.

toSet() method returns default HashSet object. If you want to get the LinkedHashSet object then you need to use the Collectors.toCollection() method with specifying the LinkedHashSet class.

In the later section of this tutorial, you will learn how to get the different Set object other than default HashSet.

List<String> numbers = Arrays.asList("one", "two", "one", "two", "three", "four");

// using toSet()
Set<String> set = numbers.stream()
 	.filter(number -> number.length() == 3)
	.collect(Collectors.toSet());

// without duplicates
System.out.println("Set removes the duplicates : ");
set.forEach(System.out::println);

// using toList()
List<String> list2 = numbers.stream()
	.filter(number -> number.length() == 3)
	.collect(Collectors.toList());

// without duplicates
System.out.println("List with duplicates: ");
list2.forEach(System.out::println);
 
Output:
Set removes the duplicates : 
one
two
List with duplicates: 
one
two
one
two
 

4. Java 8 Stream Collect() to Map using Collectors.toMap()


Next, In the below example program, we will learn how to convert the stream intermediate output to the Map using Collectors.toMap() method.
List<String> words = Arrays.asList("hello", "how", "are", "you", "doing", "mate");
		
Map<String, Integer> wordsLength = words.stream()
		.collect(Collectors.toMap(Function.identity(), String::length));

System.out.println("toMap() output: ");
wordsLength.forEach((key, value) -> System.out.println(key + " = "+value));
 
Output:
toMap() output: 
how = 3
doing = 5
are = 3
mate = 4
hello = 5
you = 3
Function.identity() is used to get the same object as a key and remember that always identity() method returns the map key when using toMap() method in java 8.

By default, toMap() method returns the HashMap object and if you want TreeMap you can use the overloaded toMap() method as shown in the next section.

If you observe that input list has unique values and Map does not allow the duplicates keys. So what happens if the input has duplicate values as below?
List<String> numbers = Arrays.asList("one", "two", "one", "two", "three", "four");
 
If you run the toMap() logic with the above numbers list with duplicate values then it will through the runtime exception.
Exception in thread "main" java.lang.IllegalStateException: Duplicate key one (attempted merging values 3 and 3)
	at java.base/java.util.stream.Collectors.duplicateKeyException(Collectors.java:133)
	at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Collectors.java:180)
	at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
	at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
	at com.javaprogramto.java8.collectors.collect.StreamCollectExample.main(StreamCollectExample.java:45)
 
To work with the duplicate values, we need to use another toMap() overloaded method which takes another 3rd argument that takes care for duplicate keys.

We need to define the logic for duplicate key. If the key is duplicate then add "repeated" string to the value to know that key is repeated,

This the way to handle the duplicate keys with Collectors.toMap() method.
Map<String, String> wordsCount = numbers.stream()
	.collect(Collectors.toMap(Function.identity(), Function.identity(), (oldValue, newValue) -> oldValue+" repeated"));
		
System.out.println("toMap() with dupolicates: ");
wordsCount.forEach((key, value) -> System.out.println(key + " = "+value));
 
Output:
toMap() with duplicates: 
four = four
one = one repeated
three = three
two = two repeated 

5. Java 8 Stream Collect() to Collection such as LinkedList or TreeSet using Collectors.toCollection()


As of now, we have seen toList(), toSet(), toMap() methods and which returns default ArrayList, HashSet, HashMap object as default.

If you want to get the return objects as other collection objects such as LinkedList, LinkedHashSet then use Collectors.toCollection() method.

To cast to TreeMap, you need to use the toMap() method with the Supplier as 4th argument.
// toCollection() examples
// to linkedlist
List<String> linkedList = words.stream()
	.collect(Collectors.toCollection(LinkedList::new));

System.out.println("linkedList is instance of LinkedList = "+(linkedList instanceof LinkedList));

// to linkedhashset
Set<String> linkedhHashSet = words.stream().
	collect(Collectors.toCollection(LinkedHashSet::new));
System.out.println("linkedhHashSet is instance of LinkedHashSet = "+(linkedhHashSet instanceof LinkedHashSet));

// to linkedhashset
Map<String, Integer> treeMap = words.stream()
	.collect(Collectors.toMap(Function.identity(), String::length, (oldValue, newValue) -> newValue, TreeMap::new));
System.out.println("treeMap is instance of TreeMap = "+(treeMap instanceof TreeMap));
	
 
Output:
linkedList is instance of LinkedList = true
linkedhHashSet is instance of LinkedHashSet = true
treeMap is instance of TreeMap = true	
 

6. Java 8 Stream API Collect Full Examples

package com.javaprogramto.java8.collectors.collect;

import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Examples to Java 8 Stream collect() method
 * 
 * @author JavaProgramTo.com
 *
 */
public class StreamCollectExample {

	public static void main(String[] args) {

		// toList() examples
		List<String> words = Arrays.asList("hello", "how", "are", "you", "doing", "mate");
		
		List<String> list = words.stream()
		.map(word -> word.toUpperCase())
		.collect(Collectors.toList());
		
		System.out.println("Collectors.toList() : "+list);

		
		List<String> numbers = Arrays.asList("one", "two", "one", "two", "three", "four");

		// using toSet()
		Set<String> set = numbers.stream().filter(number -> number.length() == 3).collect(Collectors.toSet());
		
		// without duplicates
		System.out.println("Set removes the duplicates : ");
		set.forEach(System.out::println);

		// using toList()
		List<String> list2 = numbers.stream().filter(number -> number.length() == 3).collect(Collectors.toList());
		
		// without duplicates
		System.out.println("List with duplicates: ");
		list2.forEach(System.out::println);
		
		// tomap() examples
		Map<String, Integer> wordsLength = words.stream().collect(Collectors.toMap(Function.identity(), String::length));
		
		System.out.println("toMap() output: ");
		wordsLength.forEach((key, value) -> System.out.println(key + " = "+value));
		
		Map<String, String> wordsCount = numbers.stream().collect(Collectors.toMap(Function.identity(), Function.identity(), (oldValue, newValue) -> oldValue+" repeated"));
		
		System.out.println("toMap() with duplicates: ");
		wordsCount.forEach((key, value) -> System.out.println(key + " = "+value));
		
		// toCollection() examples
		// to linkedlist
		List<String> linkedList = words.stream().collect(Collectors.toCollection(LinkedList::new));
		
		System.out.println("linkedList is instance of LinkedList = "+(linkedList instanceof LinkedList));
		
		// to linkedhashset
		Set<String> linkedhHashSet = words.stream().collect(Collectors.toCollection(LinkedHashSet::new));
		System.out.println("linkedhHashSet is instance of LinkedHashSet = "+(linkedhHashSet instanceof LinkedHashSet));
		
		// to linkedhashset
		Map<String, Integer> treeMap = words.stream().collect(Collectors.toMap(Function.identity(), String::length, (oldValue, newValue) -> newValue, TreeMap::new));
		System.out.println("treeMap is instance of TreeMap = "+(treeMap instanceof TreeMap));
	

	}

}

 

7. Conclusion


In this article, we've seen how to use the Collect() of java 8 Stream api with examples.

collect() method can be used to convert the stream into the List or Set or Map or LinkedList or TreeMap based on the need.

And also we can use collect() with the joining, groupingby(), partitionby(), counting().




No comments:

Post a Comment

Please do not add any spam links in the comments section.