On the definition of “sameness”
As Joachim noted, for most application, List.equals(Object o) definition works:
Compares the specified object with this list for equality. Returns
trueif and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists are equal. (Two elementse1ande2are equal if(e1==null ? e2==null : e1.equals(e2)).) In other words, two lists are defined to be equal if they contain the same elements in the same order. This definition ensures that theequalsmethod works properly across different implementations of theListinterface.
Depending on how you’re using it, though, this may not work as expected. If you have a List<int[]>, for example, it doesn’t quite work because arrays inherit equals from Object which defines equality as reference identity.
List<int[]> list1 = Arrays.asList(new int[] { 1, 2, 3 });
List<int[]> list2 = Arrays.asList(new int[] { 1, 2, 3 });
System.out.println(list1.equals(list2)); // prints "false"
Also, two lists with different type parameter can be equals:
List<Number> list1 = new ArrayList<Number>();
List<String> list2 = new ArrayList<String>();
System.out.println(list1.equals(list2)); // prints "true"
You also mentioned that the list must contain elements with the same type. Here’s yet another example where the elements don’t have the same type, and yet they’re equals:
List<Object> list1 = new ArrayList<Object>();
List<Object> list2 = new ArrayList<Object>();
list1.add(new ArrayList<Integer>());
list2.add(new LinkedList<String>());
System.out.println(list1.equals(list2)); // prints "true"
So unless you clearly define what equality means to you, the question can have very different answers. For most practical purposes, though, List.equals should suffice.
On implementing equals
Information after update suggests that List.equals will do the job just fine, provided that the elements implement equals properly (because List<E>.equals invokes E.equals on the non-null-elements, per the API documentation above).
So in this case, if we have, say, a List<Player>, then Player must @Override equals(Object o) to return true if o instanceof Player and on the relevant fields, they’re all equals (for reference types) or == (for primitives).
Of course, when you @Override equals, you should also @Override int hashCode(). The barely acceptable minimum is to return 42;; slightly better is to return name.hashCode();; best is to use a formula that involves all the fields on which you define equals. A good IDE can automatically generate equals/hashCode methods for you.
See also
- Effective Java 2nd Edition
- Item 8: Obey the general contract when overriding equals
- Item 9: Always override hashcode when you override equals
API links
Object.equals(Object)Object.hashCode()java.lang.Comparable– not needed here, but another important Java API contract
Related questions
On equals/hashCode combo:
- Overriding equals and hashcode in Java
- Why both hashCode() and equals() exist
- How to ensure hashCode() is consistent with equals()?
On equals vs ==:
- Difference between equals and ==
- why equals() method when we have == operator?
- Java String.equals versus ==