Java Modifying Elements in a foreach
Asked Answered
A

4

5

I'm learning Java on my own; and therefore the code below has no function other than for learning/testing.

Essentially I'm trying to modify the elements of an Integer array (namely, halving them) whilst in a foreach loop.

I should note that I'm not re-ordering, adding, or deleting elements; simply changing their values.

Here is my code:

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

However, the original array (intArray) is this:

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

And the output of copyArray is:

[47, 31, 71, 76, 78]

So although the array has been halved in size, the elements (Integers) haven't also been halved in value. So what am I doing wrong?

Thank you

Ament answered 14/6, 2012 at 11:36 Comment(3)
I think this has to do with autoboxing, so when you do x/2, it isn't modifying the object's value, but automatically converts it to a primitive int and divides it, therefore your Integer instance is not affected.Klute
So is the /= operator only applicable on 'int' value types, and not Integers, leading the 'x' variable to be converted to an int?Ament
Essentially x = x/2 is a x = new Integer(x.intValue()/2). So since you aren't adding it back to the array, you aren't getting your array elements modified.Klute
T
13

You can't do that in a foreach loop.

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

Else you are not assigning it back into the array. Integer objects are immutable by the way so can't modify them (creating new ones though).

Updated from comment: Beware though that there are a few things going on, autoboxing/unboxing for example, roughly:

copyArray[i] = Integer.valueOf(copyArray[i].intValue()/2);
Thormora answered 14/6, 2012 at 11:41 Comment(5)
Considering their immutability, that just means it will replace the Integer object with a new one in the array?Ament
Correct. In this case there is autoboxing/unboxing going on as well. So simliar too: copyArray[i] = Integer.valueOf(copyArray[i].intValue()/2);Thormora
So is Integer just an object wrapper for int? Not an actual alias (like in C#)?Ament
Yes in java it is an Object wrapper, and automatic boxing an unboxing is done for them.Thormora
Thanks, @ryan, updated code to use the length field.Thormora
B
1
for (int i = 0; i< copyArray.length; i++) {
    copyArray[i] = new Integer(x /2);
}

should work.

Boer answered 14/6, 2012 at 11:39 Comment(0)
K
1
int counter = 0;
for(int x : copyArray)
{
        x /= 2;
        copyArray[counter++] = x;
}

Your program just modified the value of variable x , not the values within the blocks of array copyArray

Korte answered 14/6, 2012 at 11:45 Comment(0)
S
0

I think that you can NOT use the foreach loop construct in order to modify the elements of the array you are iterating. Instead, you need to use a classic for loop like so:

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));
Stomacher answered 14/6, 2012 at 11:47 Comment(1)
In general, you CAN modify the elements (if they're mutable), the real problem is that Integers are immutable...Silicious

© 2022 - 2024 — McMap. All rights reserved.