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