I'm wondering if there is a way to easily modify the ".contains()" method in the List interface in Java without creating a custom class. For example:
When dealing with a collection of arrays in java, the .contains() method will always return false because the .contains() method always checks for equality with a generic .equals() call from the Object class that only returns true if the compared objects have the same reference in memory. However, with arrays, it is much more useful to do an Arrays.equals() check on the two arrays.
Code:
public class Temp {
public static void main(String[] args) {
int[] myIntArray = new int[] {1, 2, 3};
List<int[]> myList = new ArrayList<>();
myList.add(myIntArray);
System.out.println(myList.contains(new int[] {1, 2, 3}));
} // Output in the console: false
// Preferred output: true
}
I understand that it is possible to do this rather easily by using a for loop and iterating over the whole list using the Arrays.equals() method, but the goal for me is to learn how to easily sculpt the .contains() method into what I need for future use. Thanks a lot!
No. contains()
can't do anything other than use Object.equals
, because that's required by the specification.
That's not to say that it's not reasonable to want a notion of contains for an array; merely that you can't overload the existing concept.
You can straightforwardly create a static method:
static <T> boolean containsArray(List<? extends T[]> list, T[] query) {
return list.stream().anyMatch(e -> Arrays.equals(e, query));
}
And then invoke this where you would otherwise invoke list.contains(query)
.
This has the advantage that it works for any list (with reference-typed array elements): you don't have to create it specially, merely update these specialized comparisons.
(The above would work for any reference-typed array. You'd need to specialize it for primitive-typed arrays).
It also has the advantage that you don't have to deal with the thorny consequences highlighted by Stephen C (e.g. how indexOf
, remove
etc work).
There's another alternative: use a list element type which supports equals "correctly". For example, you can wrap arrays using Arrays.asList
to store them in the list, so you have a List<List<T>>
instead of List<T[]>
.
This would be quite an invasive change: it would require changing the type of the list throughout your code; you've not provided any indication of how pervasively-used your list of arrays is.