简体   繁体   English

java 中 Integer、AtomicInteger 之间的区别

[英]Difference between Integer, AtomicInteger in java

When I am working with optional class of java like below当我使用 java 的可选 class 时,如下所示

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

The above code is not working(Error: java: local variables referenced from a lambda expression must be final or effectively final) but, when I use the AtomicInteger, It will work.上面的代码不起作用(错误:java:从 lambda 表达式引用的局部变量必须是最终的或有效的最终)但是,当我使用 AtomicInteger 时,它会起作用。 Why this happens?为什么会发生这种情况?

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

You can do it like this:你可以这样做:

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

And if the Optional value can be nullable then:如果Optional值可以为空,那么:

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

Optional.ofNullable will prevent NPE in case of null value. Optional.ofNullable将在null值的情况下阻止NPE

The reason you're getting this error in the first example is that in lambda expression you're not allowed to change the reference of the local variables.在第一个示例中出现此错误的原因是在 lambda 表达式中不允许更改局部变量的引用。 That's why they need to be either declared final or effectively final.这就是为什么它们需要被宣布为final的或实际上是最终的。

And the reason the second example is working because here you're not changing the reference of the total variable.第二个示例之所以有效,是因为在这里您没有更改total变量的引用。 You're only updating its value using its set() method.您只是使用它的set()方法更新它的值。

The AtomicInteger class protects an underlying int value by providing methods that perform atomic operations on the value. AtomicInteger class 通过提供对值执行原子操作的方法来保护底层 int 值。 It shall not be used as a replacement for an Integer class.它不能用作 Integer class 的替代品。

the primary use of AtomicInteger is when we are in multi-threaded context and we need to perform atomic operations on an int value without using synchronized keyword. AtomicInteger 的主要用途是当我们处于多线程上下文中时,我们需要在不使用同步关键字的情况下对 int 值执行原子操作。

Using the AtomicInteger is equally faster and more readable than performing the same using synchronization.使用 AtomicInteger 比使用同步执行同样的操作更快、更易读。

In this case you are not just observing a difference between the two classes, but rather a difference in how you are using them.在这种情况下,您不仅观察到两个类之间的差异,而且还观察到您使用它们的方式的差异。

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

This attempts to assign a new reference, a reference to a different Integer object, to b .这试图分配一个的引用,一个对不同Integer object 的引用,给b This would neither be allowed with Integer , AtomicInteger or any other type. IntegerAtomicInteger或任何其他类型都不允许这样做。

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

This calls a method ( set ) in the existing AtomicInteger object.这将调用现有AtomicInteger set中的方法 ( set )。 Calling a method from within a lambda is allowed for both Integer , AtomicInteger and all other classes. IntegerAtomicInteger和所有其他类都允许从 lambda 中调用方法。 One important difference for your use case, though, is that Integer hasn't got a method that allows you to change the value since the class is immutable.但是,您的用例的一个重要区别是Integer没有一种方法可以让您更改值,因为 class 是不可变的。

What to do instead?该怎么做? See the good answer by Mushif Ali Nawaz .请参阅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? 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?

You asked why the behaviour of Integer and AtomicInteger is different in your case.您问为什么IntegerAtomicInteger的行为在您的情况下有所不同。 The reason really has nothing to do with AtomicInteger .原因确实与AtomicInteger无关。 Rather the difference is that Integer is immutable and, therefore, the only way of changing the value of a reference to an Integer is through assignment.相反,不同之处在于Integer是不可变的,因此,更改对Integer的引用值的唯一方法是通过赋值。 But lambda expressions do not allow assignment to a local variable that is outside the scope of the expression.但是 lambda 表达式不允许分配给表达式的 scope 之外的局部变量。

There are several ways you could resolve this without using AtomicInteger :有几种方法可以在不使用AtomicInteger的情况下解决此问题:

  1. create your own MutableInteger that can be set inside the lambda创建您自己的MutableInteger可以在 lambda 中设置
  2. make the Integer an object variable rather than local variable使Integer成为 object 变量而不是局部变量
  3. use orElse or the various alternatives to return the value rather than setting it inside ifPresent使用orElse或各种替代方法来返回值,而不是在ifPresent中设置它

Note also that you might consider OptionalInt rather than Optional<Integer> .另请注意,您可能会考虑OptionalInt而不是Optional<Integer>

They behave differently because you are doing two totally things.他们的行为不同,因为您正在做两件事。

In your first:在你的第一个:

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

The variable “total” represents an area in memory that you are changing the value of.变量“total”表示 memory 中您正在更改其值的区域。 That is what is not allowed.那是不允许的。

In the second:在第二:

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

The variable “total” represents an area in memory that is referencing (or pointing to) an instance of the class AtomicInteger.变量“total”表示 memory 中引用(或指向)class AtomicInteger 实例的区域。 You are not changing that variable, but simply calling a method on it.您没有更改该变量,而只是在其上调用方法。 Since “total” itself remains unchanged, it is what is termed “effectively final”, and so is allowed.由于“总”本身保持不变,因此被称为“有效最终”,因此是允许的。

暂无
暂无

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

相关问题 AtomicReference 和 AtomicReference 有什么区别<Integer>与 AtomicInteger 对比? - What´s the difference between AtomicReference<Integer> vs. AtomicInteger? AtomicInteger 与 Integer 的性能差异 - Performance Difference of AtomicInteger vs Integer java Integer 的 ConcurrentHashMap 与 AtomicInteger 的 HashMap 与 AtomicInteger 的 ConcurrentHashMap - java ConcurrentHashMap of Integer vs HashMap of AtomicInteger vs ConcurrentHashMap of AtomicInteger AtomicInteger.updateAndGet()和AtomicInteger.accumulateAndGet()之间是否存在任何功能差异? - Is there any functional difference between AtomicInteger.updateAndGet() and AtomicInteger.accumulateAndGet()? Java中的Integer和int有什么区别? - What is the difference between Integer and int in Java? Java中的AtomicInteger VS同步的int变量:性能差异 - AtomicInteger Vs synchronized int variable in Java : performance difference List 和 List 有什么区别<Integer[]>并列出<List<Integer> &gt; 在 Java 中 - What is the difference between List<Integer[]> and List<List<Integer>> in java Java中的Atomic Integer和Normal immutable Integer类有什么区别? - What is the difference between Atomic Integer and Normal immutable Integer class in Java? java中的(Integer)y和new Integer(y)有什么区别? - What is the difference between (Integer)y and new Integer(y) in java? Java AtomicInteger getAndIncrement()和compareAndSet - Java AtomicInteger getAndIncrement() and compareAndSet
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM