【问题标题】:Why is .contains returning false when I add a duplicate? [closed]当我添加重复项时,为什么 .contains 返回 false? [关闭]
【发布时间】:2020-10-01 13:38:20
【问题描述】:

我正在编写一个简单的方法来将一个对象添加到 ArrayList(如果它还没有包含它)。我正在使用 .contains 方法,但由于某种原因,当我将对象的副本添加到 ArrayList 时,.contains 方法返回 false,即使我已经将相同的对象添加到了 ArrayList。

这是我的City 班级:

class City {
  private String name, country;
  //getters, setters, constructor
}

当我有这样的ArrayList 时:

List<City> destinations = new ArrayList<>();

添加了一个对象

destinations.add(new City("Edmonston", "CA"));

如果我检查它是否包含这样的重复对象,它会返回 false

destinations.contains(new City("Edmonston", "CA"))

这是完整的代码:

主要方法 ,

输出

城市等级

旅行类

感谢您的帮助!

【问题讨论】:

  • 请添加文字而不是图片链接,尤其是那些难以阅读的图片。我几乎看不到你的 Trip 课程
  • 问题可能是你没有覆盖你的equalshashCode 方法。根据docs,它使用Objects.equals方法来比较元素。 Objects.equals(a, b) 首先检查两个参数是否为null,然后使用a.equals(b) 检查它们是否相同
  • 循环不适合你吗?
  • @user 在什么情况下我必须重写 hashCode 方法?我测试了只是覆盖 equals 方法,它工作正常。
  • @gili.g 当您使用HashSetHashMap 等时,它们会使用您对象的哈希码

标签: java arraylist contains


【解决方案1】:

请参阅下面给出的documentation of List#contains

如果此列表包含指定元素,则返回 true。更多的 正式地,当且仅当此列表包含至少一个时才返回 true 元素 e 使得 Objects.equals(o, e)。

因此,您需要覆盖class City 中的equals 方法。你可以这样做:

@Override
public boolean equals(Object obj) {
    City other = (City) obj;
    return Objects.equals(name, other.name) && Objects.equals(country, other.country);
}

【讨论】:

    【解决方案2】:

    为了使contains() 正常工作,您必须在您的类中覆盖equals()hashCode() 方法。如果你不这样做,那么相等的基础是引用的对象是一个且相同的。

    例如:

    City c1 = new City("London", "UK") ;
    City c2 = new City("London", "UK") ;
    System.out.println(c1.equals(c2)) ;    // prints false
    c2 = c1 ;
    System.out.println(c1.equals(c2)) ;    // prints true
    

    编辑:要覆盖 equals() 方法,请参阅 Arvind Kumar Avinash 的回答。

    【讨论】:

      【解决方案3】:

      根据documentationcontains 方法的工作方式是它使用Objects.equals(o, e),其中o 是您要检查的对象存在于ArrayList 中,e 是每个元素在数组中。

      Objects.equals(a, b) 首先检查两个参数是否为null,然后使用a.equals(b) 检查它们是否相同。

      默认情况下,Object 中的equals 方法只执行a == b,仅当ab 完全相同时返回true,即ab 两者引用内存中的相同位置,不关心对象内部的变量。

      City c = new City("foo", "bar");
      c == new City("foo", "bar") //not true
      c == c //true
      

      因为equals的这个默认实现:

      City c = new City("foo", "bar");
      c.equals(new City("foo", "bar")) //not true
      c.equals(c) //true
      

      因此,您需要在 City 类中重写 equals 方法,以便检查 2 个 City 对象是否相等。 Arvind Kumar Avinash 的 answer 提供了一种方法来做到这一点。

      但是,每个集合都可以以不同的方式实现contains 和类似方法。 HashSets 可以使用对象的哈希码来比较它们。因此,为您的类重写 hashCode 方法也很重要。

      public int hashCode() {
        return Objects.hash(name, country);
      }
      

      【讨论】:

        【解决方案4】:

        如果您只想在列表中插入一个 City 对象,请使用 HashSet 并覆盖 City 类中 Object 类的 equals() 和 hashCode() 方法。

         public static void main(String[] args) {
        
            Set<City> list = new HashSet<City>();
        
            list.add(new City("Edmonston", "CA"));
            list.add(new City("Edmonston", "CA"));
            list.add(new City("Edmonston", "CA"));
        
            System.out.println(list); //Edmonston in CA
        }
        

        还有你的 City 类:

        class City {
        
        private String name, country;
        
         public City(String s1, String s2) {
                this.name = s1;
                this.country = s2;
            }
        
         @Override
        public boolean equals(Object obj) {
             if (obj instanceof City)
                 return this.name == ((City) obj).name & this.country == ((City) obj).country;
             else
                 return false;
        }
        
        
        
         @Override
        public int hashCode() {
        
             return this.country.hashCode() + this.name.hashCode();
        
        }
        
        
         @Override
            public String toString() {
                return this.name + " in " + this.country;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-06-20
          • 2020-07-26
          • 2016-03-29
          • 2011-05-22
          • 2021-09-23
          • 1970-01-01
          • 2021-02-02
          相关资源
          最近更新 更多