【问题标题】:Java 8 variable should be final or effectively final issue [duplicate]Java 8变量应该是最终的或有效的最终问题[重复]
【发布时间】:2021-08-18 03:25:27
【问题描述】:

我正在使用 Java 8 流迭代和一个也应该在其他类中使用的变量。所以我使用了下面的代码。

AtomicBoolean bool = new AtomicBoolean(true);
public void testBool(){
list.stream().forEach(c->{ 
      if( c.getName() != null){
    bool.set(true);
    }
});

}

public void test(){
  if(bool.get()){
    System.out.println("value is there");
  }
}

但我听说使用原子对象有时会影响性能。是否有任何替代方法可以使用 Java 8 使用 forEach 块之外的变量? 如果没有这个,我会得到错误,因为变量应该是最终或有效的最终错误。

请帮我解决这个问题。

提前致谢。

【问题讨论】:

  • 您在 lambda 函数中编写的所有代码都必须是 functional 这意味着:在 lambda 函数中执行的任何代码都不应该对其他任何地方产生影响。您的代码对变量 bool 有这种影响,这就是它阻止它做同样事情的原因。请使用不同的逻辑,例如:list.stream().any( c -> c.getName != null )
  • duplicate link 中最受好评的三个答案应该可以为您提供足够的信息。
  • 使用AtomicBoolean 的“性能”影响非常小,几乎无法衡量。但是,使用在不需要时迭代每个元素的流而不是使用在找到第一个getName != null 时提前退出的简单循环对性能的影响非常大,即使大小非常适中也很容易测量列表。
  • 有效最终限制仅适用于局部变量。因为您正在设置一个实例字段,所以您可以简单地使用:boolean bool = true; 并在 lambda 中进行设置。

标签: java java-8 java-stream atomicinteger atomic-values


【解决方案1】:

如果有任何名称不为空,您可以使用 lambda 表达式返回 true 或 false,并将结果分配给您的布尔值,从而避免该问题。

类似这样的:

boolean hasAnyWithNames = list.stream().anyMatch(c -> c.getName() != null);

顺便说一句,选择“bool”对于变量名来说不是一个好选择。

编辑:

  • 将 Boolean 替换为每个评论的基本类型。
  • 使用 anyMatch() 而不是 filter() 每个评论计数 谢谢

【讨论】:

  • 使用anyMatch,而且,不要无缘无故地使用Boolean对象。只是boolean。 “hasEmptyNames”是“有任何不为空的名称”的奇怪选择。
  • 好人!
【解决方案2】:

有效的最终限制仅适用于局部变量。
由于您正在设置实例字段,因此您可以简单地使用: boolean bool = true; 并在 lambda 中设置它。

如果需要使用局部变量,请在声明中添加final 修饰符。

关于使用 AtomicBoolean 的开销,请记住,流也有开销,如果您只将它们用于迭代,则最好使用 for 循环:

boolean bool = true;

    public void testBool(){
        for (var c : list) {
            if (c.getName() != null) {
                bool = true;
                break;
            }
        }
    }

最后,正如@Neela 在评论中提到的,更有效地使用流将使用以下代码*:

boolean bool = list.stream().anyMatch(c -> c.getName() != null);

*请注意,原始代码有一个错误导致 bool 始终为真,可以通过不预设 true 并直接放入 anyMatch 的结果来避免这种情况。

【讨论】:

  • bool 设置为anyMatch() 的结果与OP 的代码效果相同:如果bool 已经是true,但没有元素如果名称不为空,则 OP 的代码会将 bool 保留为 true,但您的代码会将其设置为 false。尽管 OP 的代码可能无法反映 OP 的意图,但您的代码仍然可能产生不同的结果。
猜你喜欢
  • 1970-01-01
  • 2018-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-23
相关资源
最近更新 更多