Java 如何将流结果存储到多个列表或映射中

Java 如何将流结果存储到多个列表或映射中,java,java-8,java-stream,Java,Java 8,Java Stream,有更好的方法吗?请注意,下面的代码正在运行 List<Object1> details1 = new ArrayList<>(); List<Object2> details2 = new ArrayList<>(); List<Object3> details3 = new ArrayList<>(); endPointList.parallelStream().forEach(endPoint -> { d

有更好的方法吗?请注意,下面的代码正在运行

List<Object1> details1 = new ArrayList<>();
List<Object2> details2 = new ArrayList<>();
List<Object3> details3 = new ArrayList<>();    
endPointList.parallelStream().forEach(endPoint -> {
details1.addAll(ConfigHelper.getConfig1(endPoint));
details2.addAll(ConfigHelper.getConfig2(endPoint));
details3.addAll(ConfigHelper.getConfig3(endPoint));
});
List details1=new ArrayList();
List details2=new ArrayList();
List details3=新的ArrayList();
endPointList.parallelStream().forEach(端点->{
details1.addAll(ConfigHelper.getConfig1(端点));
details2.addAll(ConfigHelper.getConfig2(端点));
details3.addAll(ConfigHelper.getConfig3(端点));
});

我不认为有一种内置的方法可以做到这一点。但是如果您必须经常这样做,那么编写自己的
收集器
可能是值得的。这不会使它变短,但在使用它时,它看起来更像其他收集器

public static class ConfigCollector implements Collector<EndPoint, ConfigCollector, ConfigCollector>
{
    List<Config1> config1s = new CopyOnWriteArrayList<>();
    List<Config2> config2s = new CopyOnWriteArrayList<>();
    List<Config3> config3s = new CopyOnWriteArrayList<>();

    public List<Config1> getConfig1s() { return config1s; }
    public List<Config2> getConfig2s() { return config2s; }
    public List<Config3> getConfig3s() { return config3s; }

    @Override
    public BiConsumer<ConfigCollector, EndPoint> accumulator()
    {
        return (cc, e) -> {
            cc.config1s.addAll(ConfigHelper.getConfig1(endPoint));
            cc.config2s.addAll(ConfigHelper.getConfig2(endPoint));
            cc.config3s.addAll(ConfigHelper.getConfig3(endPoint));
        };
    }

    @Override
    public Set<java.util.stream.Collector.Characteristics> characteristics()
    {
        HashSet<java.util.stream.Collector.Characteristics> set = new HashSet<>();
        set.add(Characteristics.IDENTITY_FINISH);
        set.add(Characteristics.UNORDERED);
        set.add(Characteristics.CONCURRENT);
        return set;
    }

    @Override
    public BinaryOperator<ConfigCollector> combiner()
    {
        return (cc1, cc2) -> {
            cc1.config1s.addAll(cc2.config1s);
            cc1.config2s.addAll(cc2.config2s);
            cc1.config3s.addAll(cc2.config3s);
            return cc1;
        };
    }

    @Override
    public Function<ConfigCollector, ConfigCollector> finisher()
    {
        return Function.identity();
    }

    @Override
    public Supplier<ConfigCollector> supplier()
    {
        return ConfigCollector::new;
    }
}

这将使处理其他评论者提到的并发性问题变得更容易(因为您在收集器中而不是在业务代码中处理并发性)。可能您还没有遇到这个问题,因为您的流足够小,所以它还没有并行完成任何操作。

假设您的问题有很多解决方法。不,它们都只包含在一个列表中,但在我的问题中,我必须包含多个列表。因此,上面的代码可以工作,你只是想知道是否有更好的方法来完成同样的事情?谁会投票赞成?这里没有明确的问题,因为我们不知道任何变量的数据类型。@RiteshChouhan从不从并行流中写入非线程安全的数据结构(如
ArrayList
)。
ConfigCollector configs = endPointList.parallelStream().collect(new ConfigCollector());
configs.getConfig1s();
configs.getConfig2s();
configs.getConfig3s();