Java 8 introduced the Collectors class, which provides a variety of collectors for use with streams. Collectors are used to accumulate the elements of a stream into a single result, such as a list or a map. In this article, we’ll take a closer look at the Collectors class and describe and give examples of all of its static methods.

  1. toList()

The toList() method returns a collector that accumulates the elements of a stream into a new list.

List<String> list = Stream.of("one", "two", "three").collect(Collectors.toList());
  1. toSet()

The toSet() method returns a collector that accumulates the elements of a stream into a new set.

Set<String> set = Stream.of("one", "two", "three").collect(Collectors.toSet());
  1. toMap()

The toMap() method returns a collector that accumulates the elements of a stream into a new map. It takes two functions as arguments: a key mapping function and a value mapping function.

Map<String, Integer> map = Stream.of("one", "two", "three").collect(Collectors.toMap(Function.identity(), String::length));
  1. joining()

The joining() method returns a collector that concatenates the elements of a stream into a single string, separated by a delimiter.

String joined = Stream.of("one", "two", "three").collect(Collectors.joining(", "));
  1. groupingBy()

The groupingBy() method returns a collector that groups the elements of a stream into a map based on a classifier function.

Map<Integer, List<String>> map = Stream.of("one", "two", "three")     .collect(Collectors.groupingBy(String::length));
  1. summingInt()

The summingInt() method returns a collector that calculates the sum of the elements of a stream.

int sum = IntStream.of(1, 2, 3, 4, 5).collect(Collectors.summingInt(Integer::intValue));
  1. averagingInt()

The averagingInt() method returns a collector that calculates the average of the elements of a stream.

double average = IntStream.of(1, 2, 3, 4, 5).collect(Collectors.averagingInt(Integer::intValue));
  1. maxBy()

The maxBy() method returns a collector that finds the maximum element of a stream, based on a comparator.

Optional<Integer> max = IntStream.of(1, 2, 3, 4, 5).boxed().collect(Collectors.maxBy(Comparator.naturalOrder()));
  1. minBy()

The minBy() method returns a collector that finds the minimum element of a stream, based on a comparator.

Optional<Integer> max = IntStream.of(1, 2, 3, 4, 5).boxed().collect(Collectors.maxBy(Comparator.naturalOrder()));
  1. counting()

The counting() method returns a collector that counts the elements of a stream.

long count = Stream.of("one", "two", "three")     .collect(Collectors.counting());
  1. partitioningBy()

The partitioningBy() method returns a collector that partitions the elements of a stream into two groups based on a predicate.

Map<Boolean, List<Integer>> partitioned = IntStream.of(1, 2, 3, 4, 5).boxed().collect(Collectors.partitioningBy(n -> n % 2 == 0));
  1. toCollection()

The toCollection() method returns a collector that accumulates the elements of a stream into a new collection of the specified type.

LinkedList<String> linkedList = Stream.of("one", "two", "three").collect(Collectors.toCollection(LinkedList::new));
  1. mapping()

The mapping() method returns a collector that maps the elements of a stream before accumulating them.

List<Integer> lengths = Stream.of("one", "two", "three").collect(Collectors.mapping(String::length, Collectors.toList()));
  1. reducing()

The reducing() method returns a collector that reduces the elements of a stream using a binary operator.

Optional<Integer> sum = Stream.of(1, 2, 3, 4, 5).collect(Collectors.reducing(Integer::sum));
  1. teeing()

The teeing() method returns a collector that applies two downstream collectors to the same stream and combines their results.

int sum = Stream.of(1, 2, 3, 4, 5)     
	.collect(Collectors.teeing( 
		Collectors.summingInt(Integer::intValue),
		Collectors.counting(),
		(s, c) -> s / c
	 ));
  1. summarizingInt()

The summarizingInt() method returns a collector that calculates various statistics of the elements of a stream.

IntSummaryStatistics stats = IntStream.of(1, 2, 3, 4, 5).collect(Collectors.summarizingInt(Integer::intValue));
  1. joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)

The joining() method with arguments allows customizing the delimiter, prefix, and suffix of the concatenated string.

String joined = Stream.of("one", "two", "three").collect(Collectors.joining(", ", "[", "]"));
  1. filtering()

The filtering() method returns a collector that filters the elements of a stream before accumulating them.

List<Integer> evenNumbers = Stream.of(1, 2, 3, 4, 5).collect(Collectors.filtering(n -> n % 2 == 0, Collectors.toList()));
  1. flatMap()

The flatMap() method returns a collector that applies a function to each element of a stream and flattens the results into a single stream.

List<Integer> allNumbers = Stream.of(
		Arrays.asList(1, 2),
		Arrays.asList(3, 4),
		Arrays.asList(5)
	).collect(Collectors.flatMapping(List::stream, Collectors.toList()));
  1. collectingAndThen()

The collectingAndThen() method returns a collector that applies a final transformation function to the result of another collector.

List<Integer> doubled = Stream.of(1, 2, 3, 4, 5)
	.collect(Collectors.collectingAndThen(Collectors.toList(),
		list -> list.stream().map(n -> n * 2)
	.collect(Collectors.toList())));

In conclusion, the Collectors class in Java provides a wide range of static methods that simplify the process of accumulating the elements of a stream into a collection or reducing them to a single value. With the help of these collectors, we can easily perform common operations like grouping, partitioning, counting, summing, averaging, joining, filtering, and mapping.

It is important to note that the performance of these collectors can vary depending on the characteristics of the stream, such as size, order, and parallelism. Therefore, it is recommended to use the appropriate collector for the specific use case and to benchmark the performance for large or complex streams.

I hope this article has helped you understand the various static methods available in the Collectors class and how to use them in your Java applications. With these powerful collectors, you can easily manipulate and transform the elements of a stream to meet your specific requirements. Happy coding!


Discover more from GhostProgrammer - Jeff Miller

Subscribe to get the latest posts sent to your email.

By Jeffery Miller

I am known for being able to quickly decipher difficult problems to assist development teams in producing a solution. I have been called upon to be the Team Lead for multiple large-scale projects. I have a keen interest in learning new technologies, always ready for a new challenge.