Close

Java 8 Streams - Stream.collect Examples

Java 8 Streams Java Java API 


Interface:

java.util.stream.Stream

java.lang.AutoCloseableAutoCloseablejava.util.stream.BaseStreamBaseStreamjava.util.stream.StreamStreamLogicBig

Methods:

<R> R collect(Supplier<R> supplier,
              BiConsumer<R,? super T> accumulator,
              BiConsumer<R,R> combiner)

This method performs a mutable reduction operation on the elements of this stream.

Type Parameter:
R - type of the result
Parameters:
supplier - a function that creates a new result container (mutable object) . For a parallel execution, this function may be called multiple times. It must return a fresh value each time.
accumulator - a function for incorporating an additional element into a result.
combiner - a function for combining two values, used in parallel stream, combines the results received from different threads.



<R,A> R collect(Collector<? super T,A,R> collector)

Performs a mutable reduction operation on the elements of this stream using a Collector.

Type Parameters:
R - the type of the result
A - the intermediate accumulation type of the Collector
Parameters:
collector - the Collector performing the reduction.


Examples


In this example the mutable container is AtomicInteger

package com.logicbig.example.stream;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Supplier;

public class CollectExample {

public static void main(String... args) {
List<Integer> list = Arrays.asList(1, 3, 5, 11, 14);

Supplier<AtomicInteger> supplier = AtomicInteger::new;

BiConsumer<AtomicInteger, Integer> accumulator =
(AtomicInteger a, Integer i) -> {
a.set(a.get() + i);
};

BiConsumer<AtomicInteger, AtomicInteger> combiner =
(a1, a2) -> {
a1.set(a1.get() + a2.get());
};

AtomicInteger result = list.stream()
.collect(supplier, accumulator, combiner);
System.out.println(result);
}
}

Output

34




Rewriting above example to use Collector. We are implementing the Collector interface.

package com.logicbig.example.stream;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;

public class CollectExample2 {

public static void main(String... args) {
List<Integer> list = Arrays.asList(1, 3, 5, 11, 14);
AtomicInteger result = list.stream().collect(sumCollector);
System.out.println(result);
}

public static final Collector<Integer, AtomicInteger, AtomicInteger> sumCollector =
new Collector<Integer, AtomicInteger, AtomicInteger>() {
@Override
public Supplier<AtomicInteger> supplier() {
return AtomicInteger::new;
}

@Override
public BiConsumer<AtomicInteger, Integer> accumulator() {
return (a, i) -> {
a.set(a.get() + i);
};
}

@Override
public BinaryOperator<AtomicInteger> combiner() {
return (a1, a2) -> {
AtomicInteger a = new AtomicInteger();
a.set(a1.get() + a2.get());
return a;
};
}

@Override
public Function<AtomicInteger, AtomicInteger> finisher() {
return a -> a;
}

@Override
public Set<Collector.Characteristics> characteristics() {
return Collections.emptySet();
}
};
}

Output

34




In this example our mutable container is StringBuffer and we are concatenating stream strings elements to it.
This example is also comparing the collect() method with an equivalent reduce() method.

package com.logicbig.example;

import java.util.Arrays;
import java.util.List;

public class MutableReductionExample {
public static void main (String[] args) {
List<String> list = Arrays.asList("Mike", "Nicki", "John");
runMutableCollect(list);
runImmutableReduce(list);
}

private static void runMutableCollect (List<String> list) {
String s = list.stream().collect(StringBuilder::new,
(sb, s1) -> sb.append(" ").append(s1),
(sb1, sb2) -> sb1.append(sb2.toString())).toString();
System.out.println(s);
}

private static void runImmutableReduce (List<String> list) {
String s = list.stream().reduce("", (s1, s2) -> s1 + " " + s2);
System.out.println(s);
}
}

Output

 Mike Nicki John
Mike Nicki John
Original Post




In this example the mutable container is the ArrayList and we are adding stream elements to it.

package com.logicbig.example;


import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

public class MutableReductionExample2 {
public static void main (String[] args) {
IntStream stream = IntStream.range(1, 100);
List<Integer> list = stream.parallel()
.filter(i -> i % 10 == 0)
.collect(ArrayList::new, ArrayList::add
, ArrayList::addAll);
System.out.println(list);
}
}

Output

[10, 20, 30, 40, 50, 60, 70, 80, 90]
Original Post




See Also