-1

In case of CopyOnWriteArrayList, a new object is created whenever an element is added into the collection.

Consider below example:

   private static void copyOnWriteArrayList() {
    List<String> playersUsing2 = new CopyOnWriteArrayList<String>();
    System.out.println("Original hashCode = " + playersUsing2.hashCode());
    playersUsing2.add("a1");
    System.out.println("After a1 hashCode = " + playersUsing2.hashCode() + " size = " + playersUsing2.size());
    addElement(playersUsing2, "a2");
    System.out.println("After b1 from copyOnWriteArrayList hashCode = " + playersUsing2.hashCode() + " size = " + playersUsing2.size());
    playersUsing2.add("b1");
    System.out.println("After b1 hashCode = " + playersUsing2.hashCode() + " size = " + playersUsing2.size());
}

private static void addElement(List<String> playersUsingNew, String value) {
    playersUsingNew.add(value);
    System.out.println("After a2 hashCode = " + playersUsingNew.hashCode() + " size = " + playersUsingNew.size());
}

Each time when an element is added, a new object will be created, and playersUsing2 reference on the stack will be updated to point to that memory location. Understandable.

Now, I pass playersUsing2 to another method, so a new stack frame will be created and playersUsingNew will also point to same memory location. And when a new element is added, a new object will be created and playersUsingNew will point to new memory location.

But how the first stack frame, having playersUsing2 is updated to point to latest memory location?

I saw java.util.concurrent.CopyOnWriteArrayList.add(E) implementation but couldn't understand. Is it through some native code and JVM to handle, how it happens?

Output:

Original hashCode = 1
After a1 hashCode = 3087 size = 1
After a2 hashCode = 98754 size = 2
After b1 from copyOnWriteArrayList hashCode = 98754 size = 2
After b1 hashCode = 3064461 size = 3
hagrawal7777
  • 14,103
  • 5
  • 40
  • 70
  • What do you mean by _a new object will be created, and `playersUsing2` reference on the stack_? – Sotirios Delimanolis Jul 12 '15 at 22:38
  • 2
    I think you've misunderstood the statement _A thread-safe variant of `java.util.ArrayList` in which all mutative operations (add, set, and so on) are implemented by making a fresh copy of the **underlying array**._ – Sotirios Delimanolis Jul 12 '15 at 22:41
  • @SotiriosDelimanolis But then why I see a new hashcode value each time after a mutative operation. I added the o/p of run. – hagrawal7777 Jul 12 '15 at 22:43
  • Is it that a new hashcode doesn't guarantee to be a new object? – hagrawal7777 Jul 12 '15 at 22:44
  • Do you expect an object's hashCode to be a permanent, unchanging value? It's not; mutative operations will generally change it. Try the same experiment with a regular ArrayList. – user2357112 Jul 12 '15 at 22:44
  • Ok, I just saw the `hashcode` of `CopyOnWriteArrayList` and they have overridden it and doing this - `hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());`. So, it got it now. – hagrawal7777 Jul 12 '15 at 22:46
  • @user2357112 I got it now. For `ArrayList` they are not overriding `hashcode` so I will get same value each time, after mutative operation. – hagrawal7777 Jul 12 '15 at 22:53
  • [No you won't.](http://ideone.com/CnOqQF) – Sotirios Delimanolis Jul 12 '15 at 22:55
  • @SotiriosDelimanolis Oh yes. I called hashcode of some other object; I think I am trying to go too fast to cover many things. – hagrawal7777 Jul 12 '15 at 23:04
  • @SotiriosDelimanolis One quick question if you don't mind - all mutative operations are synchronized, but then why a new array is prepared under the hoods, sole purpose was to allow iterator to work on the original copy? But then only upon `iterator()` a new copy of array (holding list value) could have been created and let Iterator work on it. No? – hagrawal7777 Jul 12 '15 at 23:28
  • [The hash code of an object is not its memory address.](http://stackoverflow.com/questions/2427631/how-is-hashcode-calculated-in-java) – Raedwald Jul 20 '15 at 15:32
  • @Raedwald How about this from `Object#hashCode()` docs - "*This is typically implemented by converting the internal address of the object into an integer*". Now `hashCode()` is a native implementation. My understanding of this is that if `hashCode()` is not overridden by the class, and the JVM implementation has implemented `hashCode()` (which I think should be) in such a way that it returns the internal address of the object, then in these scenarios `hashCode()` is guaranteed to return the internal address of the object. No? – hagrawal7777 Jul 20 '15 at 15:59
  • "This is typically implemented by converting the internal address of the object into an integer" that statement is false. And "internal address" need not mean "memory address". – Raedwald Jul 20 '15 at 16:04
  • @Raedwald I have no say if you think Java docs are wrong. "*And "internal address" need not mean "memory address".*" What is your definition of internal address? – hagrawal7777 Jul 20 '15 at 17:00

1 Answers1

0

Well it is a misconception to conclude that hash code change represents a creation of new object.The value returned by hashCode() is by no means guaranteed to be the memory address of the object.

user373830
  • 63
  • 1
  • 8
  • "*The value returned by hashCode() is by no means guaranteed to be the memory address of the object.*" If `hashCode()` is not overridden then typically it is true. And I had figured out that in case of `CopyOnWriteArrayList` and `ArrayList`, it is overridden. Thank for your note though. – hagrawal7777 Jul 20 '15 at 11:24