4

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.

rai.skumar
  • 10,309
  • 6
  • 39
  • 55

2 Answers2

10

What the API is saying is that:

  1. You can't add() anything that isn't an E;
  2. 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.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 1
    but what's point in searching for anything when compiler ensures that you can put only E ? – rai.skumar Jan 23 '13 at 16:44
  • 2
    @rai.skumar you could go searching for a supertype of `E`. For instance, you could have a `List` and a `Number`, and be able to check if that `Number` is in the `List` – matts Jan 23 '13 at 16:49
  • @rai.skumar: I've added an example to the answer. – NPE Jan 23 '13 at 16:52
3

Here's a good explanation: Why does Set.contains() take an Object, and not E?

splungebob
  • 5,357
  • 2
  • 22
  • 45