Introduction
In Java, the Collectors
class is part of the java.util.stream
package, introduced in Java 8. It provides a set of static methods that are used to collect the elements of a stream into collections like lists, sets, or maps. This class facilitates performing complex operations on collections in a functional style, which is one of the key features introduced with Java Streams.
With the advent of the Stream API, Java became a more functional programming-friendly language. The Collectors
class plays a pivotal role in this by providing various predefined implementations that can be easily applied to Streams. Instead of manually collecting elements from a Stream, developers can use Collectors
to perform aggregation, summarization, and transformation in a concise and readable manner.
The Role of the Collectors
Class
The Collectors
class is an essential part of Java’s Stream API. Its primary role is to provide factory methods that return Collector
instances for collecting elements from streams into various data structures. A Collector
is a strategy used to accumulate the elements of a stream into a mutable result, such as a collection or a value. The Collectors
class offers a range of predefined implementations, making it easy to use Streams with minimal code.
Key Features of the Collectors
Class
- Predefined Collectors:
Collectors
provides a variety of predefined collector implementations such astoList()
,toSet()
, andjoining()
, among others. - Aggregation and Summarization: The class includes collectors like
summarizingInt()
,summarizingDouble()
, andsummarizingLong()
to summarize data in various ways. - Grouping and Partitioning: It also provides functionality to group or partition elements based on criteria using
groupingBy()
andpartitioningBy()
. - Composing Collectors: You can combine multiple collectors using
andThen()
to perform composite collection operations.
Commonly Used Methods of the Collectors
Class
Let’s explore some of the most commonly used methods provided by the Collectors
class.
toList()
The toList()
collector is one of the simplest and most commonly used collectors. It collects the elements of a stream into a List
.
import java.util.*;
import java.util.stream.*;
public class ToListExample {
public static void main(String[] args) {
List names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List result = names.stream()
.filter(name -> name.length() > 3)
.collect(Collectors.toList());
System.out.println(result); // Output: [Alice, Charlie, David]
}
}
toSet()
The toSet()
collector collects the elements of a stream into a Set
, ensuring that duplicates are removed automatically.
import java.util.*;
import java.util.stream.*;
public class ToSetExample {
public static void main(String[] args) {
List names = Arrays.asList("Alice", "Bob", "Charlie", "Alice");
Set result = names.stream()
.collect(Collectors.toSet());
System.out.println(result); // Output: [Alice, Bob, Charlie]
}
}
joining()
The joining()
collector is used to concatenate the elements of a stream into a single string. It can also take a delimiter, a prefix, and a suffix for customization.
import java.util.*;
import java.util.stream.*;
public class JoiningExample {
public static void main(String[] args) {
List names = Arrays.asList("Alice", "Bob", "Charlie");
String result = names.stream()
.collect(Collectors.joining(", ", "[", "]"));
System.out.println(result); // Output: [Alice, Bob, Charlie]
}
}
groupingBy()
The groupingBy()
collector groups the elements of a stream by a classifier function. This can be useful for categorizing data.
import java.util.*;
import java.util.stream.*;
public class GroupingByExample {
public static void main(String[] args) {
List names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");
Map> groupedByLength = names.stream()
.collect(Collectors.groupingBy(String::length));
System.out.println(groupedByLength); // Output: {3=[Bob, Eve], 5=[Alice], 7=[Charlie, David]}
}
}
partitioningBy()
The partitioningBy()
collector partitions the elements of a stream into two groups based on a predicate. It returns a Map
.
import java.util.*;
import java.util.stream.*;
public class PartitioningByExample {
public static void main(String[] args) {
List names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");
Map> partitioned = names.stream()
.collect(Collectors.partitioningBy(name -> name.length() > 3));
System.out.println(partitioned); // Output: {false=[Bob, Eve], true=[Alice, Charlie, David]}
}
}
Advanced Uses of Collectors
Apart from basic collection operations, Collectors
can be used for more advanced data processing tasks like reducing, summarizing, or even transforming data in streams.
reducing()
The reducing()
collector performs a reduction on the elements of a stream using an associative accumulation function and returns an Optional
result.
import java.util.*;
import java.util.stream.*;
public class ReducingExample {
public static void main(String[] args) {
List numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional sum = numbers.stream()
.collect(Collectors.reducing(Integer::sum));
System.out.println(sum.orElse(0)); // Output: 15
}
}
summarizingInt()
The summarizingInt()
collector provides a summary of the elements of a stream, including count, sum, min, average, and max.
import java.util.*;
import java.util.stream.*;
public class SummarizingIntExample {
public static void main(String[] args) {
List numbers = Arrays.asList(1, 2, 3, 4, 5);
IntSummaryStatistics stats = numbers.stream()
.collect(Collectors.summarizingInt(Integer::intValue));
System.out.println(stats); // Output: IntSummaryStatistics{count=5, sum=15, min=1, average=3.000000, max=5}
}
}
Conclusion
The Collectors
class is a powerful tool in Java that simplifies working with collections and Streams. It provides an intuitive API for performing complex operations like aggregation, grouping, and summarization. By using the Collectors
class, developers can write concise, readable, and efficient code when working with data in a functional style.