2013-05-22 39 views
9

说我有它填充了不同类型的对象一个ArrayList ...为什么ArrayList.contains(Object.class)不能用于查找实例类型?

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); 

我想找出是否shelf包含Orange对象。我试过

shelf.contains(Orange.class) 

但是这不会返回true。我的理解是,contains使用equals方法进行对象比较,所以我不确定为什么会出现这种情况。

我意识到我可以简单地遍历ArrayList并单独检查对象的类型,但我很好奇为什么contains不按我期望的方式工作。

回答

17

你是正确的,contains使用equals。然而,一个类的实例不等于该类的一个对象,即Orange.class.equals(new Orange())是错误的。

您将需要一个自定义方法来检查包含类实例的列表。

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

下面是一个Java 8版本制作使用Stream API和lambda表达式:

public static <E> boolean containsInstance(List<E> list, Class<? extends E> clazz) { 
    return list.stream().anyMatch(e -> clazz.isInstance(e)); 
} 
+0

这是我当前如何实施的检查,但我认为使用'contains'可能让我消除循环。我误解了类实例和实际对象之间的区别。感谢澄清。 – voidHead

-1

从Javadoc文档ArrayList#contains

返回true,如果此列表包含指定的元素。更正式地说,当且仅当该列表包含至少一个元素e(例如(o == null?e == null:o.equals(e))时才返回true。

您需要为contains方法提供一个类的实例,而不是类对象。

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); 

shelf.contains(apple); // returns true 
0

试试这个:

boolean containsObjectOfType(Object o){ 
for (int i=0;i<shelf.getSize();i++){ 
    if (shelf.get(i).getClass().equals(o.getClass())){ 
    return true; 
    } 
} 
return false; 
} 
相关问题