1

I have this problem of object references which is driving me crazy. Is it normal that when I get an Integer[] array from an object and modify some elements in this variable, it gets modified in the object as well without using any set method? For example below I want to modify timetable variable locally but not in the bestSoFar object. How can I do this? and what is really happening here?

for (IntTuple examRel: examsRel) 
{   
     int[] examsTogether = examRel.getData();
     double maxFitness = 0.0;
     Integer[] timetable = bestSoFar.getChromosome();

     for (int i=0; i < noOfTimeslots; i++)
     { 
          for (int j=0; j < examsTogether.length; j++)
          {
               timetable[examsTogether[j]] = i;
          }

          BestChromosome thisChromosome = evaluateChromosome(new BestChromosome(timetable));
          double thisFitness = thisChromosome.getFitness();

          if (thisFitness > maxFitness)
          {
              maxFitness = thisFitness;
              bestSoFar = thisChromosome;
          }
       }
    }
    return bestSoFar;
}
4
  • 1
    Evidently getChromosome() is returning a reference to the underlying storage, rather than creating a copy first. Commented May 3, 2014 at 17:18
  • Yes, it is normal, because you get reference to Integer[] array. If you need other behavior, you should consider cloning array before returning it. Commented May 3, 2014 at 17:19
  • A Array is a normal object. you have a reference on it and you can change its member. You must create a copy of it. You can use Arrays.copyOf (docs.oracle.com/javase/7/docs/api/java/util/…) for it Commented May 3, 2014 at 17:19
  • so I need to copy the array into another Integer[] array for example? Commented May 3, 2014 at 17:19

2 Answers 2

5

An array in Java is an Object, so when you modify its elements, they change for all the references pointing to that array. If you want a local copy, you should clone it. E.g.:

Integer[] origTimetable = bestSoFar.getChromosome();
Integer[] timetable = Arrays.copyOf (origTimetable, origTimeable.length);
Sign up to request clarification or add additional context in comments.

4 Comments

thanks for your answer. So if I have a copy of this timetable and modify that instead, the timetable in chromosome wouldnt be modified. But would this be avoided if the array was a primitive int[] ?
@Bernice no, using primitive ints wouldn't help - the object reference here is the array itself - your code wasn't modifying the existing elements, it was switching them with different ones. The exact same problem would occur with an array of primitive ints.
ok and same goes for the object of BestChromosome. where I am doing bestSoFat = thisChromosome I would be making them equal by having the same reference for both objects right?
@Bernice yup. Both variables would be pointing to the same reference.
1

Yes, it's normal. The method is returning a reference to the array that is contained in your object. If you change what the array contains, the array is thus modified.

You'll have to make a defensive copy of the array before returning it.

You could avoid these copies by using a List<Integer> instead, and return an unmodifiable view of this list to prevent its modification. It would then be up to the caller to create a copy of the list if it needs to modify it:

return Collections.unmodifiableList(list);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.