Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't ArrayList.contains(Object.class) work for finding instances types?

Tags:

java

arraylist

Say I have an ArrayList which is populated with objects of different types...

ArrayList<Fruit> shelf = new ArrayList<Fruit>();
Apple apple = new Apple();
Orange orange = new Orange();
Pear pear = new Pear();

shelf.add(apple);
shelf.add(orange);
shelf.add(pear);

I want to find out if shelf contains an Orange object. I've tried

shelf.contains(Orange.class)

but this doesn't return true. My understanding is that contains makes use of the equals method for object comparison, so I'm not sure why this is the case.

I realise I can simply iterate through the ArrayList and check the type of the objects individually, but I'm curious as to why contains doesn't behave the way I expect it to.

like image 769
x4nd3r Avatar asked May 22 '13 00:05

x4nd3r


People also ask

Can ArrayList contain object?

To check if ArrayList contains a specific object or element, use ArrayList. contains() method. You can call contains() method on the ArrayList, with the element passed as argument to the method. contains() method returns true if the object is present in the list, else the method returns false.

Can ArrayList contain different types?

It is more common to create an ArrayList of definite type such as Integer, Double, etc. But there is also a method to create ArrayLists that are capable of holding Objects of multiple Types.

How do you use contains in a list of objects?

contains() is implemented by calling equals() on each object until one returns true . So one way to implement this is to override equals() but of course, you can only have one equals. Frameworks like Guava therefore use predicates for this. With Iterables.

How many objects can an ArrayList store?

Since ArrayList in Java is backed by a built-in array, the limit on the size is equal the same as the limit on the size of an array, i.e. 2147483647. Since your project is for android platform, you would run out of memory before reaching this limit. However, 8000 is a relatively small number.


1 Answers

You are correct, contains uses equals. However, an instance of a class is not equal to an object of the class, i.e. Orange.class.equals(new Orange()) is false.

You will need a custom method to check for a list containing an instance of a class.

public static <E> boolean containsInstance(List<E> list, Class<? extends E> clazz) {
    for (E e : list) {
        if (clazz.isInstance(e)) {
            return true;
        }
    }
    return false;
}

And here's a Java 8 version making use of the Stream API and lambdas:

public static <E> boolean containsInstance(List<E> list, Class<? extends E> clazz) {
    return list.stream().anyMatch(e -> clazz.isInstance(e));
}
like image 68
FThompson Avatar answered Sep 29 '22 23:09

FThompson