Streams are a wonderful feature in Java allowing you to write clean, efficient and powerful code.

If you haven't consumed the output of the stream, you will probably want to collect it. That's when the methods from Java.util.stream.Collectors come to help.

Here are some useful examples:

  • Collect to list:

List<String> asdfgh = Arrays.asList("asd", "fgh");
List<String> fgh = asdfgh.stream().filter(x -> x.contains("a")).collect(Collectors.toList());

We start with a list of strings containing "asd" and "fgh". With a predicate we filter the values which contain "a" and then collect the result to a new list.

  • Collect to map:

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class Friend {

	int id;
	String name;

	public int getId() {
		return id;
	}

	public String getName() {
		return name;
	}

	public Friend(int id, String name) {
		this.id = id;
		this.name = name;
	}

}

public class Test {

	public static void main(String[] args) {

		Friend niceGuy = new Friend(0, "Joe");
		Friend badGuy = new Friend(1, "Donald");

		List<Friend> myFriends = new ArrayList<>();
		myFriends.add(niceGuy);
		myFriends.add(badGuy);

		Map<Integer, String> friendsMap = myFriends.stream().collect(Collectors.toMap(Friend::getId, Friend::getName));

	}
}

This example is a bit more complex in order to make sense. There is a class Friend which is needed for the Collectors.toMap functions implementations. So in the end we convert a list of Friend objects to a map of integers and strings.

There are also other Collectors method such as toSet and toConcurrentMap which are similar to the above.