Collectors Class – toList(), toSet() and toMap() methods
This post will discuss toList()
, toSet()
, and toMap()
methods of Collectors
class in Java.
1. Using Collectors.toList()
method
Collectors.toList()
method returns a Collector
which collects all the input elements into a new list. It doesn’t offer any guarantee on the type of list returned.
⮚ Get a list from the specified values
1 2 |
List<Integer> list = Stream.of(1, 2, 3, 4, 5) .collect(Collectors.toList()); |
⮚ Convert a primitive array to a list
1 2 3 4 5 |
int[] array = { 1, 2, 3, 4, 5 }; List<Integer> list = Stream.of(array) // returns `Stream<int[]>` .flatMapToInt(Arrays::stream) .boxed() .collect(Collectors.toList()); |
⮚ Convert a non-primitive array to a list
1 2 3 |
Integer[] arr = { 1, 2, 3, 4, 5 }; List<Integer> list = Stream.of(arr) .collect(Collectors.toList()); |
⮚ Convert string to list of Characters
1 2 3 |
List<Character> chars = "Techie".chars() // IntStream .mapToObj(e -> (char)e) // Stream<Character> .collect(Collectors.toList()); |
2. Using Collectors.toSet()
method
Collectors.toSet()
method works in the similar way as Collectors.toList()
but returns a set which discards the duplicates present in the input.
⮚ Get a set from specified values
1 |
Set<Integer> set = Stream.of(1, 2, 3, 4, 5).collect(Collectors.toSet()); |
⮚ Convert a primitive array to a set
1 2 3 4 5 |
int[] array = { 1, 2, 3, 4, 5 }; Set<Integer> set = Stream.of(array) // returns `Stream<int[]>` .flatMapToInt(Arrays::stream) .boxed() .collect(Collectors.toSet()); |
⮚ Convert a non-primitive array to a set
1 2 |
Integer[] arr = { 1, 2, 3, 4, 5 }; Set<Integer> set = Stream.of(arr).collect(Collectors.toSet()); |
3. Using Collectors.toMap()
method
Since a stream is a sequence of items, to construct a map out of it, we need to specify how to extract keys/values pairs. The Collectors.toMap()
returns a Collector
that collects all the input elements into a new map by applying the specified mapping functions to the input elements, which help identify the keys and values.
1 2 3 4 5 |
Map<String, String> map = Stream.of(new String[][] { {"A", "value1"}, {"B", "value2"}, {"C", "value3"} }).collect(Collectors.toMap(p -> p[0], p -> p[1])); |
If we want a map with different types for key and value, we can do something like :
1 2 3 4 5 |
Map<String, Integer> map = Stream.of(new Object[][] { {"A", 65}, {"B", 66}, {"C", 67} }).collect(Collectors.toMap(p -> (String)p[0], p -> (Integer)p[1])); |
Another approach to accommodate different types for keys and values is to use the AbstractMap.SimpleEntry<K,V>
or AbstractMap.SimpleImmutableEntry<K,V>
, which are just implementations of the Map.Entry<K,V>
interface.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import java.util.AbstractMap; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; class Main { public static void main(String[] args) { Map<String, String> person = Stream.of( new AbstractMap.SimpleEntry<>("Name", "John"), new AbstractMap.SimpleEntry<>("Age", "26"), new AbstractMap.SimpleEntry<>("Sex", "Male") ).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); for (String key: person.keySet()) { System.out.println(key + " is " + person.get(key)); } } } |
Output:
Sex is Male
Age is 26
Name is John
We can also use an overloaded version of the Collectors.toMap()
method to specify the desired map type and how to deal with collisions between multiple values mapping to the same key.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import java.util.AbstractMap; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.stream.Collectors; class Main { public static void main(String[] args) { List<Map.Entry<String, String>> entries = Arrays.asList( new AbstractMap.SimpleEntry<>("Name", "John"), new AbstractMap.SimpleEntry<>("Age", "26"), new AbstractMap.SimpleEntry<>("Sex", "Male") ); Map<String, String> treeMap = entries.stream() .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> newValue, TreeMap::new)); for (String key: treeMap.keySet()) { System.out.println(key + " is " + treeMap.get(key)); } } } |
Output:
Age is 26
Name is John
Sex is Male
This is equivalent to:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import java.util.*; class Main { public static void main(String[] args) { List<Map.Entry<String, String>> entries = Arrays.asList( new AbstractMap.SimpleEntry<>("Name", "John"), new AbstractMap.SimpleEntry<>("Age", "26"), new AbstractMap.SimpleEntry<>("Sex", "Male") ); Map<String, String> treeMap = new TreeMap<>(); for (Map.Entry<String, String> entry : entries) { treeMap.put(entry.getKey(), entry.getValue()); } for (String key: treeMap.keySet()) { System.out.println(key + " is " + treeMap.get(key)); } } } |
Output:
Age is 26
Name is John
Sex is Male
That’s all about the Collectors
class in Java 8.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)