为什么 for-each 循环不允许递增 Integer?

发布于 2024-10-17 01:36:28 字数 263 浏览 4 评论 0原文

我的意思是在这段代码中:

List<Integer> list = new LinkedList();
list.add(1);
list.add(2);
list.add(3);

for (Integer i : list)
    i++;

System.out.println(list.get(0))

返回 1 而不是 2。在 for-each 循环中,Java 创建新对象 (i) 并从 List 中的对象复制字段值?

I mean in this code:

List<Integer> list = new LinkedList();
list.add(1);
list.add(2);
list.add(3);

for (Integer i : list)
    i++;

System.out.println(list.get(0))

returns 1 not 2. In for-each loop Java creates new object (i) and copies fields value from object in List?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

雪落纷纷 2024-10-24 01:36:28

整数是不可变的。

您的代码将 i 变量更改为指向具有更大值的全新 Integer 实例。

列表中的原始 Integer 实例不会(也不能)更改。

Integers are immutable.

Your code changes the i variable to point to a brand-new Integer instance with a larger value.

The original Integer instance in the list is not (and cannot be) changed.

时光沙漏 2024-10-24 01:36:28

++ 运算符不是 Integer 对象上的有效运算符,因此 Java 使用其自动装箱功能将 Integer 对象转换为 int 原语。一旦转换,int 基元就会递增。您不保存原语,因此它会丢失。

为了实现这个目标,你需要做类似的事情

List<Integer> list = new LinkedList();
list.add(1);
list.add(2);
list.add(3);


for (int index; index < list.size(); index++) {
   int value = list.get(index).intValue();
   value++;
   list.set(index, Integer.valueOf(value));
}

System.out.println(list.get(0))

上面的代码不是最优的;但它不使用自动装箱。优化的解决方案将使用 ListIterator (根据大众需求添加):^)

ListIterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
  iterator.set(iterator.get()++);
}

请注意,此循环大量使用自动装箱,如果您希望了解自动装箱在幕后的作用,下面介绍的等效解决方案不依赖于任何自动装箱。

ListIterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
  iterator.set(Integer.valueOf(iterator.get().intValue()++));
}

the ++ operator is not a valid operator on the Integer object, so Java uses it's auto-boxing features to convert the Integer object into an int primitive. Once it's converted, the int primitive is incremented. You don't save the primitive so it is lost.

To achieve the goal you need to do something like

List<Integer> list = new LinkedList();
list.add(1);
list.add(2);
list.add(3);


for (int index; index < list.size(); index++) {
   int value = list.get(index).intValue();
   value++;
   list.set(index, Integer.valueOf(value));
}

System.out.println(list.get(0))

The code above is not optimal; but it doesn't use autoboxing. An optimized solution would use a ListIterator (added by popular demand) :^)

ListIterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
  iterator.set(iterator.get()++);
}

Note that this loop uses autoboxing heavily, if you wish to get an idea of what autoboxing is doing under the covers, the equivalent solution presented below doesn't rely on any autoboxing.

ListIterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
  iterator.set(Integer.valueOf(iterator.get().intValue()++));
}
玻璃人 2024-10-24 01:36:28

它确实允许这样做,但它不会做你认为它会做的事情。

你所拥有的是简写。

for (Iterator<Integer> iter = list.iterator(); iter.hashNext();) {
    Integer i = iter.next();
    i++; // value is discarded after this line.
}

编辑:更好的选择是使用 ListIterator,而不是使用 get(i) 和 set(i, value),这对于 LinkedList 来说可能非常昂贵。

for (ListIterator<Integer> iter = list.listIterator(); iter.hasNext();)
    iter.set(iter.next()+1);

It does allow it, it doesn't do what you think it does.

What you have is shorthand for.

for (Iterator<Integer> iter = list.iterator(); iter.hashNext();) {
    Integer i = iter.next();
    i++; // value is discarded after this line.
}

EDIT: rather than using get(i) and set(i, value) which can be very expensive for LinkedList, a better choice would be to use ListIterator.

for (ListIterator<Integer> iter = list.listIterator(); iter.hasNext();)
    iter.set(iter.next()+1);
沉睡月亮 2024-10-24 01:36:28

因为列表中的第 0 个元素是“1”,您在第 2 行中添加了它。

哦,我明白了:您想要增加整数。您必须这样做:

for( int i=0; i<list.size(); i++ ) {
    list.set(i,list.get(i)+1);
}

请注意,Integer 实例是不可变的。数值不能改变!

Because the 0th element in the list is the "1", which you added in line 2.

Oh, I understand: You want to increment the integers. You have to do:

for( int i=0; i<list.size(); i++ ) {
    list.set(i,list.get(i)+1);
}

Please note that Integer instances are immutable. The value cannot change!

兔姬 2024-10-24 01:36:28

因为 Integer 是不可变的,就像 String 等。

整数上的运算符 ++ 就像做:

i = new Integer(i.intValue()+1);`

你需要 < code>list.set(index, i); 修改列表中的值。

for (int index=0; index<list.size(); index++) {
   list.set(index, list.get(index)+1);
}

Because Integer is immutable, just like String, etc.

The operator ++ on an integer is just like doing :

i = new Integer(i.intValue()+1);`

You'll need to list.set(index, i); to modify the value in your list.

for (int index=0; index<list.size(); index++) {
   list.set(index, list.get(index)+1);
}
若能看破又如何 2024-10-24 01:36:28

由于所有答案都与不变性有关,因此可变类型的外观如下:

import java.util.concurrent.AtomicInteger;


List<AtomicInteger> list = new LinkedList<AtomicInteger>();
list.add(new AtomicInteger(1));
list.add(new AtomicInteger(2));
list.add(new AtomicInteger(3));

for (AtomicInteger i : list)
    i.getAndIncrement();

System.out.println(list.get(0));

这应该输出 2。 (AtomicInteger 另外具有这些线程安全属性,但我们在这里只需要可变性。)

基元类型 int (与所有基元一样)也是不可变的,因此以下变体仍然会输出 1:

int[] list = new int[]{ 1, 2, 3};

for (int i : list)
    i++;

System.out.println(list[0]);

Since all the answers are about immutability, here how it would look with a mutable type:

import java.util.concurrent.AtomicInteger;


List<AtomicInteger> list = new LinkedList<AtomicInteger>();
list.add(new AtomicInteger(1));
list.add(new AtomicInteger(2));
list.add(new AtomicInteger(3));

for (AtomicInteger i : list)
    i.getAndIncrement();

System.out.println(list.get(0));

This should output 2. (AtomicInteger additionally has these thread-safety properties, but we need here only the mutability.)

The primitive type int (as all primitives) is immutable, too, so the following variant would still output 1:

int[] list = new int[]{ 1, 2, 3};

for (int i : list)
    i++;

System.out.println(list[0]);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文