繁体   English   中英

java 中 Integer、AtomicInteger 之间的区别

[英]Difference between Integer, AtomicInteger in java

当我使用 java 的可选 class 时,如下所示

Integer total = null;
Optional<Integer> b = Optional.of(new Integer(10));
b.ifPresent(b -> total =b);

上面的代码不起作用(错误:java:从 lambda 表达式引用的局部变量必须是最终的或有效的最终)但是,当我使用 AtomicInteger 时,它会起作用。 为什么会发生这种情况?

Optional<Integer> b = Optional.of(new Integer(10));
AtomicInteger total = new AtomicInteger();
b.ifPresent(b -> total.set(b));

你可以这样做:

Integer total = Optional.of(new Integer(10)).orElse(null);

如果Optional值可以为空,那么:

Integer total = Optional.ofNullable(new Integer(10)).orElse(null);

Optional.ofNullable将在null值的情况下阻止NPE

在第一个示例中出现此错误的原因是在 lambda 表达式中不允许更改局部变量的引用。 这就是为什么它们需要被宣布为final的或实际上是最终的。

第二个示例之所以有效,是因为在这里您没有更改total变量的引用。 您只是使用它的set()方法更新它的值。

AtomicInteger class 通过提供对值执行原子操作的方法来保护底层 int 值。 它不能用作 Integer class 的替代品。

AtomicInteger 的主要用途是当我们处于多线程上下文中时,我们需要在不使用同步关键字的情况下对 int 值执行原子操作。

使用 AtomicInteger 比使用同步执行同样的操作更快、更易读。

在这种情况下,您不仅观察到两个类之间的差异,而且还观察到您使用它们的方式的差异。

b.ifPresent(b -> total =b);

这试图分配一个的引用,一个对不同Integer object 的引用,给b IntegerAtomicInteger或任何其他类型都不允许这样做。

b.ifPresent(b -> total.set(b));

这将调用现有AtomicInteger set中的方法 ( set )。 IntegerAtomicInteger和所有其他类都允许从 lambda 中调用方法。 但是,您的用例的一个重要区别是Integer没有一种方法可以让您更改值,因为 class 是不可变的。

该怎么做? 请参阅Mushif Ali Nawaz 的好答案

PS If you want to know more about the difference between the two classes, see this question: What is the difference between Atomic Integer and Normal immutable Integer class in Java?

您问为什么IntegerAtomicInteger的行为在您的情况下有所不同。 原因确实与AtomicInteger无关。 相反,不同之处在于Integer是不可变的,因此,更改对Integer的引用值的唯一方法是通过赋值。 但是 lambda 表达式不允许分配给表达式的 scope 之外的局部变量。

有几种方法可以在不使用AtomicInteger的情况下解决此问题:

  1. 创建您自己的MutableInteger可以在 lambda 中设置
  2. 使Integer成为 object 变量而不是局部变量
  3. 使用orElse或各种替代方法来返回值,而不是在ifPresent中设置它

另请注意,您可能会考虑OptionalInt而不是Optional<Integer>

他们的行为不同,因为您正在做两件事。

在你的第一个:

b.ifPresent(b -> total =b);

变量“total”表示 memory 中您正在更改其值的区域。 那是不允许的。

在第二:

b.ifPresent(b -> total.set(b));

变量“total”表示 memory 中引用(或指向)class AtomicInteger 实例的区域。 您没有更改该变量,而只是在其上调用方法。 由于“总”本身保持不变,因此被称为“有效最终”,因此是允许的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM