Why aren't Java Collections remove methods generic?java
Map as well as in
Collection) is not generic because you should be able to pass in any type of object to
remove(). The object removed does not have to be the same type as the object that you pass in to
remove(); it only requires that they be equal. From the specification of
remove(o) removes the object
e such that
(o==null ? e==null : o.equals(e)) is true. Note that there is nothing requiring o and e to be the same type. This follows from the fact that the
equals() method takes in an Object as parameter, not just the same type as the object.
Although it may be commonly true that many classes have
equals() defined so that its objects can only be equal to objects of its own class, that is certainly not always the case. For example, the specification for List.equals() says that two List objects are equal if they are both Lists and have the same contents, even if they are different implementations of List. So coming back to the example in this question, it is possible to have a
Map<ArrayList, Something> and for me to call
remove() with a
LinkedList as argument, and it should remove the key which is a list with the same contents. This would not be possible if
remove() were generic and restricted its argument type.
Why isn't Collection.remove(Object o) generic?
Collection<E> could have
boolean remove(E o);
Then, when you accidentally try to remove (for example)
Set<String> instead of each individual String from a
Collection<String>, it would be a compile time error instead of a debugging problem later.
Java ArrayList indexOf generic type
The collection types only use their generic type
E in cases where it must match in order for the operation to be legal. If you have a list of strings then clearly something like
add can only make sense when passed a string.
But for operations like
contains it's different - it is perfectly legal to ask whether a list of strings contains a particular
Integer, for example. The answer will always be no, but that doesn't make it an error to ask the question.
That is because contains, lastIndexOf, remove etc. methods need to check for the equality of objects before performing corresponding actions, which done by using equals method. And equal method comes from object class which should be overridden by generic type E object. On the contarary to this get, set, add etc methods do not need any comparision.
Java List interface contains(Object o) method signature
remove methods accept any object because the they accept (and can succeed with) objects that might not be instances of
E. The contract for
returns true if and only if this collection contains at least one element e such that (o==null ? e==null : o.equals(e))
o need not actually be an object in the collection; it must merely pass the
The same idea goes for
See also this thread, where it is pointed out that making
remove generic would have broken a lot of existing, perfectly valid code.