Inconsistent arguments in ArrayList methods
java
Solution
What the API is saying is that:
- You can't `add()` anything that isn't an `E`;
- You are, however, allowed to go searching for things that are not `E` (but that could compare equal to an instance of `E`).
Consider the following example:
public class Main {
public static class Key {
private final int k;
public Key(int k) {
this.k = k;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Key)) {
return false;
}
Key rhs = (Key)obj;
return k == rhs.k;
}
@Override
public int hashCode() {
//...
return 0;
}
}
public static class Data extends Key {
private final int d;
public Data(int k, int d) {
super(k);
this.d = d;
}
}
public static void main(String[] args) {
List<Data> l = new ArrayList<Data>();
l.add(new Data(123, 456));
l.add(new Data(42, 24));
System.out.println(l.contains(new Key(789)));
System.out.println(l.contains(new Key(123)));
System.out.println(l.contains(new Key(42)));
}
}
The last three lines wouldn't compile if `contains()` were restricted to taking `Data`.
Problem
In ArrayList API add() takes an argument of generic parameter type, but contains() and indexOf() take arguments of type Object. ``` public class ArrayList<E> ...{ public boolean add(E e); public boolean contains(Object o); public int indexOf(Object o); .... } ``` Java Doc for ArrayList So i am just wondering if its something to do with Generics or it's design in-consistency ? I looked at Openjdk implementation but couldn't find any specific reason for this.