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

时间:2011-02-09 16:05:58

标签: java foreach integer

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

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中的对象复制字段值?

6 个答案:

答案 0 :(得分:9)

++运算符不是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()++));
}

答案 1 :(得分:8)

Integer是不可变的。

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

列表中的原始Integer实例未被(也无法)更改。

答案 2 :(得分:7)

确实允许它,它没有按照你的想法做到。

你所拥有的是简写。

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

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

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

答案 3 :(得分:0)

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

哦,我理解:你想增加整数。你必须这样做:

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

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

答案 4 :(得分:0)

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

一样

整数上的运算符++就像在执行:

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

您需要list.set(index, i);修改列表中的值。

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

答案 5 :(得分:0)

由于所有的答案都是关于不变性的,所以这里看起来是多变的:

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]);