0

In the following example:

public static void main(String[] args){

        List<String> list = new ArrayList<String>();

        list.add("hi");
        list.add("hi");
        list.add("hi");

        list.remove("hi");

        System.out.println(list); //prints [hi, hi]

}

The ArrayList is reduced by one but which one does it remove? Does it remove the last inserted or the earliest inserted one?

ziggy
  • 15,677
  • 67
  • 194
  • 287

3 Answers3

7

From the docs - Removes the first occurrence of the specified element from this list, if it is present.

Petar Minchev
  • 46,889
  • 11
  • 103
  • 119
  • 1
    Note that this is a property of all `List`s not just `ArrayList`: http://docs.oracle.com/javase/6/docs/api/java/util/List.html – The Nail Dec 04 '11 at 19:57
4

Since List#add() is documented to add to the end of the list, and List#remove(Object) is documented to return the first matching item it encounters, your call above will remove the earliest inserted instance of the string "hi."

Since the printed representation of the three objects in the list are all the same, it's hard to see the difference in behavior. However, if you look at the instance addresses in a debugger, noting which one entered the list first, you'll confirm that it's also the first—and only—one to be removed.

In your case, given that you're using string literals, they are interned by the compiler (per §3.10.5 of the JLS), so you'll see three of the same instance present in your list. In order to produce distinct String instances, try changing your three insertion calls to the following:

/* not final */ String h = "h";
list.add(h + "i"); // not interned, instance 1
list.add(h + "i"); // not interned, instance 2
list.add(h + "i"); // not interned, instance 3

Compare what you see in the debugger using those statements with your original program. Do you see a difference?

Note that if the String instance h above is declared as final, then the three concatenations will in fact all be interned, yielding the same String instance being added to the list three times. Thanks to @xehpuk for correcting my initial mistake regarding the final qualifier.

seh
  • 14,999
  • 2
  • 48
  • 58
  • Have you tested your code? They are indeed interned because of the `final` allowing the compiler to replace `h` with `"h"`, so there are three references to the *same* String instance. – xehpuk Feb 14 '12 at 14:46
  • Before I posted the answer, I did test the code, which motivated me to write the last two paragraphs. It sounds like you're seeing something different. I'll test it again today and report back on my findings. – seh Feb 16 '12 at 15:31
  • Testing again today, I see that you are correct, @xehpuk. Perhaps I had added the *final* qualifier only in the code block that I pasted into my answer. I corrected my answer and acknowledged your contribution. – seh Feb 16 '12 at 15:40
2

It will remove the first occurence it encounters, so the first one you added.

talnicolas
  • 13,885
  • 7
  • 36
  • 56