Why for-each loop does not allow increment Integer?
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 o开发者_运维知识库bject in List?
Integer
s 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.
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()++));
}
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);
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!
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);
}
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]);
精彩评论