The Startup
Published in

The Startup

Java Collectors and Its 20 Methods

Collectors is a final class that extends the Object class. It provides reduction operations, such as accumulating elements into collections, summarizing elements according to various criteria, etc. Java Collectors class provides various methods to deal with elements.

1. Creating list: toList()

It is used to accumulate elements into a list. It will create a new list (It will not change the current list).

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);integers.stream().map(x -> x*x).collect(Collectors.toList());// output: [1,4,9,16,25,36,36]

2. Creating set: toSet()

It is used to accumulate elements into a set, It will remove all the duplicate entries.

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);integers.stream().map(x -> x*x).collect(Collectors.toSet());// output: [1,4,9,16,25,36]

3. Creating specific collection: toCollection()

We can accumulate data in any specific collection as well.

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);
integers
.stream()
.filter(x -> x >2)
.collect(Collectors.toCollection(LinkedList::new));
// output: [3,4,5,6,6]

Here we are accumulating elements in a linked list.

4. Counting elements: Counting()

It will return the number of elements present in the computed collection.

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);
Long collect = integers
.stream()
.filter(x -> x <4)
.collect(Collectors.counting());
// output: 3

5. Finding minimum value: minBy()

It will return the minimum value present in a list.

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);
List<String> strings = Arrays.asList("alpha","beta","gamma");
integers
.stream()
.collect(Collectors.minBy(Comparator.naturalOrder()))
.get();
// output: 1strings
.stream()
.collect(Collectors.minBy(Comparator.naturalOrder()))
.get();
// output: alpha

It will return 1 and alpha, as per the natural order of integers and string.

We can reverse the order using reverseOrder() method.

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);
List<String> strings = Arrays.asList("alpha","beta","gamma");
integers
.stream()
.collect(Collectors.minBy(Comparator.reverseOrder()))
.get();
// output: 6strings
.stream()
.collect(Collectors.minBy(Comparator.reverseOrder()))
.get();
// output: gamma

We can have a custom comparator for the user-defined objects.

6. Finding maximum value: maxBy()

It is similar to the minimum value method, here we use maxBy() method to get the maximum value.

List<String> strings = Arrays.asList("alpha","beta","gamma");strings
.stream()
.collect(Collectors.maxBy(Comparator.naturalOrder()))
.get();
// output: gamma

All the comparator logic which were there in minBy() also apply to maxBy().

7. Partitioning a list: partitioningBy()

It is used for partitioning a list into 2 lists and adding it to the map, 1 that satisfies a given condition and another which does not satisfy like separating odd numbers from the list. So it will make 2 entries in the map, 1 with true as key and odd numbers as value and 2nd with false as key and even numbers as value.

List<String> strings = Arrays.asList("a","alpha","beta","gamma");Map<Boolean, List<String>> collect1 = strings
.stream()
.collect(Collectors.partitioningBy(x -> x.length() > 2));
// output: {false=[a], true=[alpha, beta, gamma]}

Here we are separating the strings with lengths greater than 2 from the remaining strings.

8. Creating unmodifiable list: toUnmodifiableList()

It is used to create a read-only list. Any try to make a change in this unmodifiable list will result in UnsupportedOperationException.

List<String> strings = Arrays.asList("alpha","beta","gamma");List<String> collect2 = strings
.stream()
.collect(Collectors.toUnmodifiableList());
// output: ["alpha","beta","gamma"]

9. Creating unmodifiable set: toUnmodifiableSet()

It is used to create a read-only set. Any try to make a change in this unmodifiable set will result in UnsupportedOperationException.

List<String> strings = Arrays.asList("alpha","beta","gamma","alpha");Set<String> readOnlySet = strings
.stream()
.sorted()
.collect(Collectors.toUnmodifiableSet());
// output: ["alpha","beta","gamma"]

10. Joining elements: joining()

Collectors can be used to create a string by joining all the elements of a collection, with or without any delimiter, suffix, and prefix.

List<String> strings = Arrays.asList("alpha","beta","gamma");String collect3 = strings
.stream()
.distinct()
.collect(Collectors.joining(","));
// output: alpha,beta,gammaString collect4 = strings
.stream()
.map(s -> s.toString())
.collect(Collectors.joining(",","[","]"));
// output: [alpha,beta,gamma]

In the first example we are joining string by passing a delimiter value (“,”) and in second we are passing the value of prefix and suffix.

11. Averaging long: averagingLong()

Finds the average value of a collection of long values.

NOTE: It will return a Double value, not a long value.

List<Long> longValues = Arrays.asList(100l,200l,300l);Double d1 = longValues
.stream()
.collect(Collectors.averagingLong(x -> x * 2));
// output: 400.0

12. Averaging int: averagingInt()

Finds the average value of a collection of integer values.

NOTE: It will also return a Double value, not an int value.

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);Double d2 = integers
.stream()
.collect(Collectors.averagingInt(x -> x*2));
// output: 7.714285714285714

13. Averaging Double: averagingDouble()

Finds the average value of a collection of double values.

List<Double> doubles = Arrays.asList(1.1,2.0,3.0,4.0,5.0,5.0);Double d3 = doubles
.stream()
.collect(Collectors.averagingDouble(x -> x));
// output: 3.35

14. Creating Map: toMap()

Creates a map from the values of a collection.

List<String> strings = Arrays.asList("alpha","beta","gamma");
Map<String,Integer> map = strings
.stream()
.collect(Collectors
.toMap(Function.identity(),String::length));
// output: {alpha=5, beta=4, gamma=5}

Here we created a map with list values as keys and the number of occurrences of the value in the list as the value.

15. Handling duplicates entries of the list while creating a map

A list can contain duplicate values, so If we want to create a map out of the list and want to use the list values as keys of the map then we need to resolve the duplicate keys. As a map only contains unique keys, we can use comparators to do that.

List<String> strings = Arrays.asList("alpha","beta","gamma","beta");Map<String,Integer> map = strings
.stream()
.collect(Collectors
.toMap(Function.identity(),String::length,(i1,i2) -> i1));
// output: {alpha=5, gamma=5, beta=4}

Here, Function.identity() is pointing to the list value, and i1, i2 are the values of the duplicate keys. We can keep a single value so, here we are selecting i1 but we can compute anything using these two values like adding them, comparing and selecting the greater one, etc.

16. Summing Integers: summingInt()

Finding the sum of all the integer values present in the list. It’s not always the sum of the initial collection, which we are using like in the below example we are using the list of strings and first, we are converting each string into an integer that is equal to its length and then adding all the lengths.

List<String> strings = Arrays.asList("alpha","beta","gamma");Integer collect4 = strings
.stream()
.collect(Collectors.summingInt(String::length));
// output: 18

or direct list value sum

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);Integer sum = integers
.stream()
.collect(Collectors.summingInt(x -> x));
// output: 27

17. Summing Doubles: summingDouble()

Similar to summing integers, just it is used for double values

List<Double>  doubleValues = Arrays.asList(1.1,2.0,3.0,4.0,5.0,5.0);Double sum = doubleValues
.stream()
.collect(Collectors.summingDouble(x ->x));
// output: 20.1

18. Summing Long: summingLong()

Same as the first two, used for adding long or int values. We can use summinglong() for int values as well, but we cannot use summingInt() for long values. It is based on the concept of typecasting, which data type can be cast in which one.

List<Long> longValues = Arrays.asList(100l,200l,300l);Long sum = longValues
.stream()
.collect(Collectors.summingLong(x ->x));
// output: 600

19. Summarizing Integer: summarizingInt()

It gives all the major arithmetic operation values of the values present in the collection like the average of all values, minimum value, maximum values, count, and sum of all values.

List<Integer> integers = Arrays.asList(1,2,3,4,5,6,6);IntSummaryStatistics stats = integers
.stream()
.collect(Collectors.summarizingInt(x -> x ));
//output: IntSummaryStatistics{count=7, sum=27, min=1, average=3.857143, max=6}

Now we can extract different values using get methods like:

stats.getAverage();   // 3.857143
stats.getMax(); // 6
stats.getMin(); // 1
stats.getCount(); // 7
stats.getSum(); // 27

20. GroupingBy method: groupingBy()

GroupingBy() is an advance method to create a map out of any other collection. It itself is a very vast topic which we will cover in the next blog. SO here just for the completion let's see a few examples

List<String> strings = Arrays.asList("alpha","beta","gamma");Map<Integer, List<String>> collect = strings
.stream()
.collect(Collectors.groupingBy(String::length));
// output: {4=[beta], 5=[alpha, gamma]}

It will make the string length as key and a list of strings of that length as the value.

List<String> strings = Arrays.asList("alpha","beta","gamma");Map<Integer, LinkedList<String>> collect1 = strings
.stream()
.collect(Collectors.groupingBy(String::length,
Collectors.toCollection(LinkedList::new)));
// output: {4=[beta], 5=[alpha, gamma]}

Here we specified the type of list we want in the map (linked list).

For more information about the Collectors class please refer to the official documentation: https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store