How can I collect a Java 8 stream into a Guava ImmutableCollection?

后端 未结 5 1381
你的背包
你的背包 2020-12-13 23:48

I would like to do the following:

List list = IntStream.range(0, 7).collect(Collectors.toList());

but in a way that the resu

5条回答
  •  失恋的感觉
    2020-12-13 23:59

    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());
    

提交回复
热议问题