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.

1

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

but what's point in searching for anything when compiler ensures that you can put only E ?
@rai.skumar you could go searching for a supertype of E. For instance, you could have a List<Integer> and a Number, and be able to check if that Number is in the List
@rai.skumar: I've added an example to the answer.
3

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.