【问题标题】:Why doesn't ArrayList.contains(Object.class) work for finding instances types?为什么 ArrayList.contains(Object.class) 不能用于查找实例类型?
【发布时间】:2013-05-22 00:50:02
【问题描述】:

假设我有一个 ArrayList,其中填充了不同类型的对象...

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 的行为不符合我的预期。

【问题讨论】:

    标签: java arraylist


    【解决方案1】:

    你是对的,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;
    }
    

    这是一个使用 Stream API 和 lambdas 的 Java 8 版本:

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

    【讨论】:

    • 这就是我目前实施检查的方式,但我认为使用contains 可能让我消除了循环。我误解了类实例和实际对象之间的区别。感谢您的澄清。
    【解决方案2】:

    试试这个:

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

    【讨论】:

      【解决方案3】:

      像 Contains 这样的方法,使用 equals 方法比较两个对象, 您必须将从 Object 类继承的 equals 方法覆盖到每个新创建的类。 根据您自己类的字段覆盖它。 它应该比较对象的所有字段。 它还必须检查对象是否为 null 并检查参数是否为 instancOf 。 此链接可以提供更多帮助: https://www.geeksforgeeks.org/overriding-equals-method-in-java/

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      【解决方案4】:

      来自ArrayList#contains的Javadoc

      如果此列表包含指定元素,则返回 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
      

      【讨论】:

      • 这将检查该类的特定实例是否在列表中,而不是检查问题类型的任何对象是否在列表中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-20
      • 1970-01-01
      • 1970-01-01
      • 2015-11-27
      • 1970-01-01
      • 2016-07-16
      相关资源
      最近更新 更多