Reputation: 31
Is there any better way to do this? Note that the code below is working.
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));
});
Upvotes: 1
Views: 123
Reputation: 4555
I do not think that there is a built-in way to do this. But if you have to do it very often, it might be worth writing your own Collector
. This will not make it shorter, but it will look more like other collectors when using it.
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;
}
}
Using it like this:
ConfigCollector configs = endPointList.parallelStream().collect(new ConfigCollector());
configs.getConfig1s();
configs.getConfig2s();
configs.getConfig3s();
This will make it easier to deal with what the other commenters mentioned about concurrency (as you deal with it inside the collector instead of inside your business code). Maybe you have not run into this issue because your stream is small enough so that it has not done anything in paralllel yet.
Upvotes: 1