Java For循环,包括if to parallelStream()表达式
有没有办法将这段代码并行化:Java For循环,包括if to parallelStream()表达式,java,lambda,parallel-processing,java-stream,Java,Lambda,Parallel Processing,Java Stream,有没有办法将这段代码并行化: HashMap<String, Car> cars; List<Car> snapshotCars = new ArrayList<>(); ... for (final Car car : cars.values()) { if (car.isTimeInTimeline(curTime)) { car.updateCalculatedPosition(curTime); snapshot
HashMap<String, Car> cars;
List<Car> snapshotCars = new ArrayList<>();
...
for (final Car car : cars.values()) {
if (car.isTimeInTimeline(curTime)) {
car.updateCalculatedPosition(curTime);
snapshotCars.add(car);
}
}
我如何整合这条线?->
car.updateCalculatedPosition(curTime) 如果要并行访问列表,可能需要使用
Collections.synchonizedList
获取线程安全列表:
List<Car> snapshotCars = Collections.synchronizedList(new ArrayList<>());
好吧,假设
updateCalculatedPosition
不会影响它运行的Car
对象之外的状态,那么使用peek
就足够安全了:
List<Car> snapshotCars = cars.values()
.parallelStream()
.filter(c -> c.isTimeInTimeline(curTime))
.peek(c -> c.updateCalculatedPosition(curTime))
.collect(Collectors.toCollection(ArrayList::new));
从API的角度来看,这更安全,但不太平行-您只有在完成筛选和收集后才开始更新位置。此外,您也可以使用自己的收集器:
List<Car> snapshotCars = cars.values().parallelStream()
.filter(c -> c.isTimeInTimeline(curTime))
.collect(ArrayList::new,
(l,c) -> { c.updateCalculatedPosition(curTime); l.add(c); },
List::addAll);
List snapshotCars=cars.values().parallelStream()
.过滤器(c->c.isTimeInTimeline(curTime))
.collect(数组列表::新建,
(l,c)->{c.updateCalculatedPosition(curTime);l.add(c);},
列表::addAll);
请注意,.collect(Collectors.toList())
与.collect(Collectors.toCollection(ArrayList::new))
等效(尽管不一定相同),后者与.collect(ArrayList::new,List::add,List::addAll)
等效
因此,我们的自定义收集器会执行类似的操作,但会用一个函数替换累加器,该函数也会执行所需的附加操作。您尝试过转换为流API吗?你遇到了什么问题?当然是。现在你应该试试。“别指望我们为你做你的工作。”我想让你告诉我怎么写。我猜语义差别不大。除非OP明确表示需要
ArrayList
,否则我只会使用collector.toList()
。
List<Car> snapshotCars = cars.values()
.parallelStream()
.filter(c -> c.isTimeInTimeline(curTime))
.peek(c -> c.updateCalculatedPosition(curTime))
.collect(Collectors.toCollection(ArrayList::new));
List<Car> snapshotCars = cars.values()
.parallelStream()
.filter(c -> c.isTimeInTimeline(curTime))
.collect(Collectors.toCollection(ArrayList::new));
snapShotCars.parallelStream()
.forEach(c -> c.updateCalculatedPosition(curTime));
List<Car> snapshotCars = cars.values().parallelStream()
.filter(c -> c.isTimeInTimeline(curTime))
.collect(ArrayList::new,
(l,c) -> { c.updateCalculatedPosition(curTime); l.add(c); },
List::addAll);