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

Equals和HashMap/HashSet

傅边浩
2023-03-14
public class Employee {

   int id;
   String name;
   @Override
   equals(){ 
   return false;
       }
   }

       public static void main(String[] args) {

          HashMap<Employee,String> hk= new HashMap<Employee,String>();
          Employee e1 = new Employee();
          e1.setId(18);
          e1.setName("roohi");
          hk.put(e1, "hello");
          hk.put(e1, "hello");
          }

如果Equals方法返回false,即e1.Equals(e1)返回false。所以这些值应该相加两次,但只相加一次。谁能解释一下。我在谷歌上搜索并清除了关于HashCode和equals contract的概念,但在这里我失败了。

共有1个答案

宋臻
2023-03-14

如果仔细观察Map.Put方法

public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

如果注意到这一行代码

 if (e.hash == hash && ((k = e.key) == key || key.equals(k)))

虽然您已经重写了equal方法,但是(k=e.key)==key仍然计算为true,并且它重写了旧条目。

 类似资料:
  • 根据我所读到的, 要使用对象作为hashMap的键,它必须提供正确的重写和equals和hashCode方法的实现。HashMap get(Key k)方法调用Key对象上的hashCode方法,并将返回的hashValue应用到它自己的静态哈希函数中,以找到一个桶位置(备份数组),键和值以名为Entry(Map.Entry)的嵌套类的形式存储在这里。HashMap的内部哈希方法防御质量差的哈希函

  • 我正在Java开发一个纸牌游戏,我试图比较hashMap中的键和ArrayList中的元素(两者都是对象)。hashCode()和equals()被重写,但出现了一个错误,我不确定它的哪一部分是错误的。 这是纸牌课 我们要做的比较 错误:点击查看错误图片

  • 问题内容: 如果我为一个类实现,是否仍然需要重写该方法?还是会为之工作? 如果答案为 否 ,那么如果出现差异怎么办?比方说,我的方式长期两个对象作为内享有平等的方法是从我的方式长期在同一类的两个对象为内平等不同的。 而且,如果我实施了,是否还必须重写? 问题答案: 虽然建议(并且非常明智)暗示它(反之亦然),但这 不是 必需的。旨在在对一系列对象执行排序时使用,而仅测试直接相等性。 该链接提供了一

  • 问题内容: 假设我需要使用按某些域逻辑排序的元素。通过这种逻辑,不相等的元素的顺序无关紧要,因此compare方法可以返回0,但是在这种情况下,我不能将它们放入。 所以,问题是:这样的代码有什么缺点: 更新 : 好。如果它应该永远是方法之间的一致性,并且,作为@SPFloyd - seanizer和其他人说。如果我删除接口并移入此逻辑是否会更好甚至更好(我可以在不破坏封装的情况下做到这一点)?因此

  • 在上面的代码中,我得到的输出是: 在我做 d1.name 之后=“亚瑟” 我期望输出是

  • 问题内容: 在下面的代码示例中,将键设置为null并被调用时,将丢失所有映射并清空。 当与和一起使用时,键设置为null,则不会丢失其键值映射。 输出: 我的问题是,即使丢弃了密钥,为什么在第二个代码示例中也不会丢失其条目? 问题答案: 一个丢弃条目时,关键是不再活码强可到达。由于维护人员对键具有严格的引用,因此键仍然可以访问,并且不会丢弃条目。 关键是行为与键对象的引用有关,而不是与一次引用键的