I would like to do the following:
List list = IntStream.range(0, 7).collect(Collectors.toList());
but in a way that the resu
This is where the collectingAndThen
collector is useful:
List list = IntStream.range(0, 7).boxed()
.collect(collectingAndThen(toList(), ImmutableList::copyOf));
It applies the transformation to the List
you just built; resulting in an ImmutableList
.
Or you could directly collect into the Builder
and call build()
at the end:
List list = IntStream.range(0, 7)
.collect(Builder::new, Builder::add, (builder1, builder2) -> builder1.addAll(builder2.build()))
.build();
If this option is a bit-verbose to you and you want to use it in many places, you can create your own collector:
class ImmutableListCollector implements Collector, ImmutableList> {
@Override
public Supplier> supplier() {
return Builder::new;
}
@Override
public BiConsumer, T> accumulator() {
return (b, e) -> b.add(e);
}
@Override
public BinaryOperator> combiner() {
return (b1, b2) -> b1.addAll(b2.build());
}
@Override
public Function, ImmutableList> finisher() {
return Builder::build;
}
@Override
public Set characteristics() {
return ImmutableSet.of();
}
}
and then:
List list = IntStream.range(0, 7)
.boxed()
.collect(new ImmutableListCollector<>());
Just in case the link disappears in the comments; my second approach could be defined in a static utility method that simply uses Collector.of
. It's simpler than creating your own Collector
class.
public static Collector, ImmutableList> toImmutableList() {
return Collector.of(Builder::new, Builder::add, (l, r) -> l.addAll(r.build()), Builder::build);
}
and the usage:
List list = IntStream.range(0, 7)
.boxed()
.collect(toImmutableList());