当前位置: 首页 > 知识库问答 >
问题:

插入后更改值后在集合中添加重复元素

仲孙诚
2023-03-14

我有一个集合,其中添加了两个不同的对象。插入后,我以这样一种方式更改其中一个对象,使两个对象相等(由object类中重写的equals方法验证)。此时,我在一个集合中有两个重复的元素。现在,我尝试将这两个重复的对象添加到一个新的集合中,即使equals方法为它们返回true,我仍然能够添加它们。下面是相同的代码。谁能告诉我,我到底错过了什么?

public class BasicSetImpl{
public int num; String entry;
public BasicSetImpl(int num, String entry){
  this.num = num;
  this.entry = entry;
}

@Override
public int hashCode() {
  return Objects.hash(entry, num);
}

@Override
public boolean equals(Object obj) {
  BasicSetImpl newObj = (BasicSetImpl)obj;
  if (this.num == newObj.num)
    return true;
  else
    return false; 
}



public static void main(String[] args){
  Set<BasicSetImpl> set = new HashSet<>();
  BasicSetImpl k1 = new BasicSetImpl(1, "One");
  BasicSetImpl k2 = new BasicSetImpl(2, "Two");
  set.add(k1);
  set.add(k2);
  
  k2.num = 1;
  
  System.out.println(k1.equals(k2));  //This line returns True
  
  Set<BasicSetImpl> newSet = new HashSet<>();
  newSet.add(k1);
  newSet.add(k2);
  
  //Set.size here is two

共有1个答案

湛鸿雪
2023-03-14

基于哈希的集合,在本例中是hashset使用Objecthashcode方法计算作为对象内容的函数的哈希值。由于您同时考虑entry和num来确定对象的hashcode值,因此这两个对象具有不同的hashcode,因为它们不同于entry。因此,它们属于两个不同的散列桶,并且永远不会被识别为相同的散列桶。

但是,如果按以下方式设置条目

k2.entry = "One";

则k1和k2都具有相同的hashcode值。那么它们都属于同一个散列桶,并且根据equals方法,两个对象是相同的。因此,现在重复项被忽略。

@Override
public int hashCode() {
    return Integer.hashCode(num);
}

现在,如果没有我们通过设置k2.entry=“one”;添加的攻击,它的行为应该与您预期的一样

 类似资料:
  • 我试图向ArrayList对象添加构造函数有3个参数(int,int,hashset)的对象。当我添加一个新对象时,哈希集中的值会发生某种变化,所以我添加了错误的值。例如,我创建3个对象,添加这3组整数: 但object会收到这些: 我不明白为什么集合会改变其值。这是函数代码: 在这段代码中我: > 获取对象的ArrayListallIndexedItems,描述文本中的单词(文本在mysql表中

  • 我有一个记录。 我的

  • 小心使用“set”而不是其他内置方法,因为它不会在更改值后触发事件,正如这里的评论中指出的:如何在水豚中使用fill_in与查找(如果可能) 例如。 <代码>查找(:css,“输入[id$='捐赠\u质押\u数百']”)。设置(“10”) 我正在使用ruby、capybara和site prism。据我所知,site prism的使用方法是获取capybara节点元素,然后对其调用方法,例如单击

  • 我在Mongo DB Atlas中收集了一个用户名称。 它还在继续。 在节点中可以使用什么查询。js和mongoose找到集合中的最后一个元素了吗?当集合不断动态增加时,如何获取集合最后一个元素的id?

  • 问题内容: 我有一个关于Hibernate 3.6.7和JPA 2.0的问题。 考虑以下实体(为简洁起见,省略了一些getter和setter方法): 现在考虑这段代码: 子实体错误地两次插入到父实体的子实体列表中。 执行以下操作之一时,代码可以正常工作(列表中没有重复的条目): 删除父实体中的属性 在子级列表上执行一些读取操作(例如,用标记的取消注释行) 这显然是非常奇怪的行为。同样,当使用Ec

  • 这里一个非常常见的问题是如何执行upsert,MySQL称之为,标准支持将其作为操作的一部分。 鉴于PostgreSQL不直接支持它(在PG9.5之前),您如何做到这一点?考虑以下几点: 现在假设您要“upsert”元组,,那么新的表内容将是: 在Insert中,关于PostgreSQL中的重复更新?详细讨论了这个主题,但这是关于MySQL语法的替代方法,随着时间的推移,它增加了一些无关的细节。我