-1
public class UnderstandingMemoryManagement1 {

  private static boolean flag = false;

  public static void main(String[] args) {

    Set<String> mainNameSet = getNameSet();
    mainNameSet.add("Name-6");

    Log.logInfo(getNameSet() == mainNameSet);
    Log.logInfo(getNameSet().equals(mainNameSet));
    Log.logInfo("------main() END------");
  }
  public static Set<String> getNameSet() {

    Set<String> nameSet = new TreeSet<>();
    nameSet.add("Name-1");
    nameSet.add("Name-2");
    nameSet.add("Name-3");
    nameSet.add("Name-4");

    Set<String> otherSet = nameSet;
    otherSet.add("Name-5");

    if (!flag ) {

      flag = true;
      Log.logInfo(nameSet == otherSet);
      Log.logInfo(nameSet.equals(otherSet));
      Log.logInfo("------getNameSet() END------");
    }
    return nameSet;
  }
}

When I run the above code why the output is like below -

INFO: true 
INFO: true 
INFO: ------getNameSet() END------ 
INFO: false 
INFO: false 
INFO: ------main() END------

Why second time it is returning false why not true? As far as I know java copies the reference not the object. When it is coping the referenc not the object then it should return true for second case as well. Please explain this to me.

Istiaque Hossain
  • 2,157
  • 1
  • 17
  • 28
Arghya Pal
  • 15
  • 7

2 Answers2

2

The method getNameSet() returns a reference to a new TreeSet object each time it's called. You are calling this method three times in main() so you get three different TreeSet objects.

First false comes from comparing two different TreeSet object with == operator. These are different objects and have different reference value.

Second false comes from mainNameSet.add("Name-6"); which modifies the first TreeSet so it's no longer equal.

Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
2

You first call the getNameSet() method and store its result into the mainNameSet variable. This method contains a statement where a new TreeSet instance is constructed, and then you're returning this new instance:

Set<String> nameSet = new TreeSet<>();
...
return nameSet;

Then you're doing this:

getNameSet() == mainNameSet

You're again calling getNameSet(), which in turn constructs a new TreeSet instance and return it. For each getNameSet() call, you have distinct TreeSet instances.

This is why the comparison returns false.


Java is always pass-by-value, in case of references, that means a reference passed to a method is copied.

void handle(Dog inputDog) {
    inputDog = new Dog("Jack");
}
Dog myDog = new Dog("Fluffy");
handle(myDog);

// The name of the dog referenced by 'myDog' is still Fluffy.
// Upon calling the 'handle' method, a reference to my dog named Fluffy is
// copied to the local reference 'inputDog'. A new dog with the name Jack is
// constructed and stored into the 'inputDog' variable, which is distinct
// from the 'myDog' variable. So 'myDog' doesn't change at all.
MC Emperor
  • 22,334
  • 15
  • 80
  • 130