> For the complete documentation index, see [llms.txt](https://lin-4.gitbook.io/cs-notebook-java8/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lin-4.gitbook.io/cs-notebook-java8/custom-collectors.md).

# Collectors

![](/files/-LgDoUK6Git31iL08iF6)

## <http://www.baeldung.com/java-8-collectors>

## 1. Collectors

```java
import static java.util.stream.Collectors.*;
```

### 1.1 Collectors.toList()

It can be used for collecting all Stream elements into a List instance. The important thing to remember is the face that we can't assume any particular List implementation with this method. If you want to have more control over this, use toCollection instead.

eg:

```java
List<String> result = givenList.stream().collect(toList());
```

### 1.2 Collectors.toSet()

It can be used for collecting all Stream elements into a Set instance.

### 1.3 Collectors.toCollections()

As you probably already noticed, when using *toSet and toList* collectors, you can’t make any assumptions of their implementations. If you want to use a custom implementation, you will need to use the \_toCollection \_collector with a provided collection of your choice.

Let’s create a \_Stream \_instance representing a sequence of elements and collect them into a \_LinkedList \_instance:

```java
List<String> result = givenList.stream().collect(toCollection(LinkedList::new));
```

### 1.4 Collectors.toMap()

\_ToMap \_collector can be used to collect\_Stream\_elements into a\_Map\_instance. To do this, you need to provide two functions:

* keyMapper
* valueMapper

\_keyMapper\_will be used for extracting a\_Map\_key from a\_Stream\_element, and\_valueMapper\_will be used for extracting a value associated with a given key.

Let’s collect those elements into a Map that stores strings as keys and their lengths as values:

```java
Map<String, Integer> result = givenList.stream().collect(toMap(Function.identity(), String::length))
```

*Function.identity()*

is just a shortcut for defining function that accepts and return the same value;

### 1.5 Collectors.joining()

Joining collector can be used for joining Stream\<String> elements.

eg:

```java
String result = givenList.stream().collect(joining());// will result in: abbcccdd
//specify custom separators, prefixes, postfixes:
String result = givenList.stream().collect(joining(" "));
//result in: a bb ccc dd
String result = gicenList.stream().collect(joining(" ", "Pre-","-Post"));
//result : Pre-a bb ccc dd-Post
```

## 2. Custom Collectors

If you want to write your Collector implementation, you need to implement Collector interface and specify its three generic parameters:

```java
public interface Collector<T,A,R>{...}
```

1. **T**  the type of objects that will be available for collection.
2. **A**  the type of a mutable accumulator object,
3. **R** the type of a final result.

Let’s write an example Collector for collecting elements into an \_ImmutableSet \_instance. We start by specifying the right types:

```java
private class ImmutableSetCollector<T> implements Collector<T, ImmutableSet.Builder<T>, ImmutableSet<T>> {...}
```

Since we need a mutable collection for internal collection operation handling, we can’t use \_ImmutableSet \_for this; we need to use some other mutable collection or any other class that could temporarily accumulate objects for us.

In this case, we will go on with an \_ImmutableSet.Builder \_and now we need to implement 5 methods:

* Supplier\<Imm*utableSet.Builder\<T>>**supplier**()*
* *BiConsumer\<ImmutableSet.Builder\<T>, T>**accumulator**()*
* *BinaryOperator\<ImmutableSet.Builder\<T>>**combiner**()*
* *Function\<ImmutableSet.Builder \<T>, ImmutableSet\<T>>**finisher**()*
* *Set \<Characteristics>**characteristics**()*>

<http://www.baeldung.com/java-8-collectors>
