首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将Java8流收集到Guava ImmutableCollection中?

如何将Java8流收集到Guava ImmutableCollection中?
EN

Stack Overflow用户
提问于 2015-03-12 23:01:52
回答 5查看 24.8K关注 0票数 83

我想做以下几件事:

代码语言:javascript
复制
List<Integer> list = IntStream.range(0, 7).collect(Collectors.toList());

但在某种程度上,结果列表是Guava的ImmutableList的实现。

我知道我能做到

代码语言:javascript
复制
List<Integer> list = IntStream.range(0, 7).collect(Collectors.toList());
List<Integer> immutableList = ImmutableList.copyOf(list);

但我想直接收集到它。我试过了

代码语言:javascript
复制
List<Integer> list = IntStream.range(0, 7)
    .collect(Collectors.toCollection(ImmutableList::of));

但它抛出了一个异常:

com.google.common.collect.ImmutableCollection.add(ImmutableCollection.java:96)上的

java.lang.UnsupportedOperationException

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-12-30 23:36:08

Alexis的accepted中的toImmutableList()方法现在包含在Guava 21中,可以用作:

代码语言:javascript
复制
ImmutableList<Integer> list = IntStream.range(0, 7)
    .boxed()
    .collect(ImmutableList.toImmutableList());

编辑:ImmutableList.toImmutableList中删除了@Beta以及Release 27.1 (6242bdd)中的其他常用API。

票数 93
EN

Stack Overflow用户

发布于 2015-03-12 23:07:25

这就是collectingAndThen收集器的用处:

代码语言:javascript
复制
List<Integer> list = IntStream.range(0, 7).boxed()
                .collect(collectingAndThen(toList(), ImmutableList::copyOf));

它将转换应用于您刚刚构建的List;产生一个ImmutableList

或者,您可以直接收集到Builder中,并在最后调用build()

代码语言:javascript
复制
List<Integer> list = IntStream.range(0, 7)
                .collect(Builder<Integer>::new, Builder<Integer>::add, (builder1, builder2) -> builder1.addAll(builder2.build()))
                .build();

如果此选项对您来说有点冗长,并且您希望在许多地方使用它,您可以创建自己的收集器:

代码语言:javascript
复制
class ImmutableListCollector<T> implements Collector<T, Builder<T>, ImmutableList<T>> {
    @Override
    public Supplier<Builder<T>> supplier() {
        return Builder::new;
    }

    @Override
    public BiConsumer<Builder<T>, T> accumulator() {
        return (b, e) -> b.add(e);
    }

    @Override
    public BinaryOperator<Builder<T>> combiner() {
        return (b1, b2) -> b1.addAll(b2.build());
    }

    @Override
    public Function<Builder<T>, ImmutableList<T>> finisher() {
        return Builder::build;
    }

    @Override
    public Set<Characteristics> characteristics() {
        return ImmutableSet.of();
    }
}

然后:

代码语言:javascript
复制
List<Integer> list = IntStream.range(0, 7)
                              .boxed()
                              .collect(new ImmutableListCollector<>());

以防链接在注释中消失;我的第二种方法可以在一个只使用Collector.of的静态实用程序方法中定义。它比创建自己的Collector类更简单。

代码语言:javascript
复制
public static <T> Collector<T, Builder<T>, ImmutableList<T>> toImmutableList() {
    return Collector.of(Builder<T>::new, Builder<T>::add, (l, r) -> l.addAll(r.build()), Builder<T>::build);
}

和用法:

代码语言:javascript
复制
 List<Integer> list = IntStream.range(0, 7)
                               .boxed()
                               .collect(toImmutableList());
票数 68
EN

Stack Overflow用户

发布于 2015-03-12 23:33:00

虽然不是对我问题的直接回答(它不使用收集器),但这是一种相当优雅的方法,它不使用中间集合:

代码语言:javascript
复制
Stream<Integer> stream = IntStream.range(0, 7).boxed();
List<Integer> list = ImmutableList.copyOf(stream.iterator());

Source

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29013250

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档