Reputation: 3736
I was surprised to see that equals() is apparently overridden for ArrayList<String>
. Because contains() in Collection<> apparently compares values, not references. Of course, for Collection<Object>
, references would be compared. In the program below, shouldn't I get false on the second line?
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("Obama");
al.add("Reagan");
al.add("Bush");
al.add("Nyquist");
StringBuffer sb = new StringBuffer();
sb.append("Bush");
System.out.println("compares values? using constants " + al.contains("Bush"));
System.out.println("compares values? using local variable " + al.contains(sb.toString()));
}
run:
compares values? using constants true
compares values? using local variable true
Upvotes: 3
Views: 6797
Reputation: 21
you can try System.out.println(sb.toString().equals("Bush")); in your class and see what it returns. It will return true. So in the second case it is returning/printing true.
Upvotes: 0
Reputation: 76908
Javdaocs for List are you friend. List.contains()
relies on .equals()
:
boolean contains(Object o)
Returns true if this list contains the specified element. More formally, returns true if and only if this list contains at least one element e such that (o==null ? e==null : o.equals(e)).
String.equals()
compares the String
s contents (characters):
public boolean equals(Object anObject)
Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.
Upvotes: 5
Reputation: 198211
This is exactly the output you should expect, and Collection<Object>
would be no different. All Collection
types, unless specified otherwise, use .equals(Object)
, and differing implementations violate the Collection
contract. (And to be clear, upcasting a String
to an Object
does not change the behavior of its equals
method.)
There is some precedent -- see e.g. the TreeSet
implementations, which use comparison-based equality, and IdentityHashSet
, which uses reference equality -- but these should usually be used only when the two notions of equality match, or for significant and unusual need.
Upvotes: 4