当前位置: 首页 > 面试题库 >

java.util.HashMap和HashSet的内部实现

唐健
2023-03-14
问题内容

我一直在试图了解内部实现的java.util.HashMapjava.util.HashSet

以下是我脑中浮现出一段时间的疑虑:

  1. @Override public int hashcode()HashMap / HashSet中的重要性是什么?内部在哪里使用此哈希码?
  2. 我通常已经看到HashMap的键是Stringlike myMap<String,Object>。我可以将值映射为someObject(而不是String)myMap<someObject, Object>吗?我需要遵守哪些所有合同才能成功完成?

提前致谢 !

编辑:

  1. 我们是说键(校验!)的哈希码是在哈希表中映射值的实际对象吗?当我们这样做时,myMap.get(someKey);java在内部调用someKey.hashCode()以获取哈希表中的数字以查找结果值?

答:可以

编辑2:

  1. 在中java.util.HashSet,从何处生成哈希表的密钥?是否来自我们要添加的对象,例如。mySet.add(myObject);那么myObject.hashCode()将决定将其放置在哈希表中的什么位置?(因为我们没有在HashSet中提供密钥)。

答: 添加的对象成为关键。该值是虚拟的!


问题答案:

问题2的答案很简单-
是的,您可以使用任何您喜欢的对象。具有字符串类型键的映射被广泛使用,因为它们是命名服务的典型数据结构。但通常,您可以映射任意两种类型,例如Map<Car,Vendor>Map<Student,Course>

对于hashcode()方法,就像之前回答的一样-
每当重写equals()时,都必须重写hashcode()来遵守合同。另一方面,如果您对equals()的标准实现感到满意,则不要触摸hashcode()(因为这可能会破坏合同并导致不相等的对象产生相同的哈希码)。

实用的旁注:eclipse(可能还有其他IDE)可以仅基于类成员为您的类自动生成一对equals()和hashcode()实现。

编辑

对于您的其他问题:是的,完全正确。查看HashMap.get(Object
key);的源代码。它调用key.hashcode来计算内部哈希表中的位置(bin),并返回该位置的值(如果有的话)。

但是请谨慎使用“手工”哈希码/等于方法-如果将对象用作键,请确保哈希码之后不会更改,否则将不再找到映射的值。换句话说,用于计算均值和哈希码的字段
应为最终 字段(或在创建对象后为“ 不可 更改”)。

假设我们与String name和有联系,并且String phonenumber我们使用这两个字段来计算equals()和hashcode()。现在,我们用他的手机号码创建“ John
Doe”,并将其映射到他最喜欢的Donut商店。hashcode()用于计算哈希表中的索引(bin),这就是甜甜圈店的存储位置。

现在我们知道他有一个新的电话号码,并且我们更改了John Doe对象的电话号码字段。这将导致一个新的哈希码。并且此哈希码解析为一个新的哈希表索引-
通常不是John Do’s最喜欢的Donut商店的存储位置。

问题很明显:在这种情况下,我们想将“ John Doe”映射到Doughnut商店,而不是“ John
Doe具有特定的电话号码”。因此,我们必须谨慎对待自动生成的equals /
hashcode,以确保它们确实是我们真正想要的,因为它们可能会使用不需要的字段,从而给HashMaps和HashSets带来麻烦。

编辑2

如果将对象添加到HashSet,则Object是内部哈希表的键,该值已设置但未使用(只是Object的静态实例)。这是来自openjdk
6(b17)的实现:

// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
private transient HashMap<E,Object> map;

public boolean add(E e) {
  return map.put(e, PRESENT)==null;
}


 类似资料:
  • 我对java.util.HashMap的概念理解如下:

  • 问题内容: 采取以下示例代码行: 我想要一个。将调试器用于代码,我确实得到了。我看了看下面的代码: 合同 担保 a ,实施决定a ; 似乎是合理的。但是,我的实现需要a 而不是仅任何old 保证的恒定时间查找。如果的实现决定说a ,而该实现完全在其权限之内,那么我的实现就会受到影响。 解决此问题的最佳实践是什么? 问题答案: 如果您想要保证,请使用。

  • San CLI 是一个命令行工具,其次它是一个内置 Webpack 的前端工程化构建工具。San CLI 在架构设计上采取了微核心和插件化的设计思想,我们可以通过插件机制添加命令行命令,还可以通过插件机制定制 Webpack 构建工具,从而满足不同 San 环境的前端工程化需求。 San CLI 在兼顾 San 生态的同时,尽量做到通用化配置,在设计之初,我们希望不局限于 San 的应用范畴,做可

  • 本文向大家介绍HashMap 和 HashSet的区别,包括了HashMap 和 HashSet的区别的使用技巧和注意事项,需要的朋友参考一下 HashMap和HashSet的区别是Java面试中最常被问到的问题。如果没有涉及到Collection框架以及多线程的面试,可以说是不完整。而Collection框架的问题不涉及到HashSet和HashMap,也可以说是不完整。HashMap和Hash

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

  • 问题内容: 在Java API中,HashSet的实现使用Object作为 内部HashMap 的值, 但是HashMap允许其值为null。我认为并不需要填写该值,那么为什么要这样做呢? 问题答案: 因为HashSet合同指定了返回值(true如果指定的对象存在并被删除)。为此,它使用包装的 方法返回已删除的值。 如果要存储而不是存储对象,则对 的调用将返,这与尝试删除不存在的对象的结果没有区别