2012-06-14 4 views
5

Я изучаю Java самостоятельно; и поэтому приведенный ниже код не имеет никакой функции, кроме обучения/тестирования.Java-модификация элементов в foreach

По сути, я пытаюсь изменить элементы массива Integer (а именно, поменьше их), в то время как в цикле foreach.

Следует отметить, что я не переупорядочиваю, не добавляю или не удаляю элементы; просто меняя свои ценности.

Вот мой код:

Logger.describe("Now copying half of that array in to a new array, and halving each element"); 
Integer[] copyArray = new Integer[DEFAULT_SAMPLE_SIZE/2];  
System.arraycopy(intArray, 0, copyArray, 0, DEFAULT_SAMPLE_SIZE/2); 
for (Integer x : copyArray) x /= 2; 
Logger.output(Arrays.deepToString(copyArray)); 

Однако исходный массив (INTArray) заключается в следующем:

[47, 31, 71, 76, 78, 94, 66, 47, 73, 21] 

И выход copyArray является:

[47, 31, 71, 76, 78] 

Так что, хотя размер массива был уменьшен вдвое, элементы (целые числа) также не были уменьшены вдвое. Так что я делаю неправильно?

Спасибо

+1

Я думаю, что это имеет отношение к Autoboxing, поэтому, когда вы делаете 'х/2', не изменяя значение объекта, но автоматически преобразует его в примитивный 'int' и делит его, поэтому ваш экземпляр Integer не влияет. – maksimov

+0

Итак, оператор/= применим только к типам значений «int», а не к целым, ведущим переменную «x», которая должна быть преобразована в int? – Xenoprimate

+0

По существу 'x = x/2' - это' x = новое целое число (x.intValue()/2) '. Поэтому, поскольку вы не добавляете его обратно в массив, вы не модифицируете элементы массива. – maksimov

ответ

13

Вы не можете сделать это в цикле foreach.

for (int i=0; i<copyArray.length;i++) 
    copyArray[i] /= 2; 

Иначе вы не назначаете его обратно в массив. Integer Объекты неизменяемы, поэтому не могут их изменять (создавая новые).

Обновлено от комментариев: Остерегайтесь, однако, что есть несколько вещей происходит, Autoboxing/распаковка, например, грубо:

copyArray[i] = Integer.valueOf(copyArray[i].intValue()/2); 
+0

Учитывая их неизменность, это означает, что он заменит объект Integer новым в массиве? – Xenoprimate

+0

Правильно. В этом случае происходит автобоксинг/распаковка. Так что simliar тоже: 'copyArray [i] = Integer.valueOf (copyArray [i] .intValue()/2);' –

+0

Итак, Integer просто обертка объекта для int? Не настоящий псевдоним (например, на C#)? – Xenoprimate

1
for (int i = 0; i< copyArray.length; i++) { 
    copyArray[i] = new Integer(x /2); 
} 

должен работать.

1
int counter = 0; 
for(int x : copyArray) 
{ 
     x /= 2; 
     copyArray[counter++] = x; 
} 

Ваша программа просто изменила значение переменной x, не значения в блоках массива copyArray

0

Я думаю, что вы не можете использовать конструкцию цикла foreach, чтобы модифицировать элементы массива, который вы итерируете, с помощью . Вместо этого, вы должны использовать классический цикл так:

Logger.describe("Now copying half of that array in to a new array, and halving each element"); 
Integer[] copyArray = new Integer[DEFAULT_SAMPLE_SIZE/2];  
System.arraycopy(intArray, 0, copyArray, 0, DEFAULT_SAMPLE_SIZE/2); 
    for (int i = 0; i < copyArray.length; i++) { 
     copyArray[i] /= 2; 
    } 
Logger.output(Arrays.deepToString(copyArray)); 
+1

В общем, вы МОЖЕТЕ изменить элементы (если они изменяемы), реальная проблема в том, что целые числа неизменяемы ... – Mainguy