带有lambda的Java foreach,它使用;“外部”;变量作为参数

带有lambda的Java foreach,它使用;“外部”;变量作为参数,java,Java,嗨,我有下面的代码 int newId =0; cars.stream() .filter(c -> c.getId() == null) .forEach(c -> setId(new CarId(newId++)); 但是它不能被编译,因为变量newId不是final。有可能以某种方式修复它吗?谢谢 我建议在这种情况下使用AtomicInteger。在并行流处理的情况下,它也能很好地工作,而且(IMHO)更好:)如果需要唯一的ID(而不仅仅是顺序ID),那么

嗨,我有下面的代码

int newId =0;
cars.stream()
     .filter(c -> c.getId() == null)
     .forEach(c -> setId(new CarId(newId++));

但是它不能被编译,因为变量
newId
不是final。有可能以某种方式修复它吗?谢谢

我建议在这种情况下使用
AtomicInteger
。在并行流处理的情况下,它也能很好地工作,而且(IMHO)更好:)

如果需要唯一的ID(而不仅仅是顺序ID),那么可以将
newId
变量移动为
CarID
类的(私有?)静态成员

public class CarID {
   protected static int newID = 0;

   private final int id;

   public CarID(){
     this.id = CarID.newID++;
   }
}
(可能还会添加一些线程安全行为)

然后你可以做:

cars.stream()
     .filter(c -> c.getId() == null)
     .forEach(c -> setId(new CarId());

我建议对每个循环将其重构为良好的旧版本:

int newId = 0;
for (Car c : cars) {
   if (c.getId() == null) 
        c.setId(new CarId(newId++));
}
原因:

  • 流的结果是不确定的:您设置的ID可能有一个随机顺序,在几个执行中可能会有所不同(但我认为您可以接受)
  • 使用流时不鼓励出现副作用
  • 虽然在线程方面使用
    AtomicInteger
    很好(但速度很慢),但由于某些原因,当流要并行时,其他解决方案会导致问题

我一点也不喜欢这个。这是一个等待发生的多线程问题。此外,id生成现在已硬编码到类中,因此以后不可能切换到数据库生成的id。
c->methodName
对我帮助很大。