HashMap中的重复元素搜索和替换逻辑

时间:2015-12-18 17:22:10

标签: java collections

在求职面试中我问过这个问题,我仍然不知道答案,所以在这里问一下。让我们说key对象的hashCode()返回一个固定的整数,所以HashMap看起来像LinkedList。

  

如何找到重复的元素并用map中的新值替换?

e.g。如果按照下面列出的顺序执行1001次投注,

  

放(1000,1000),放(1,1),放(2,2),放(3,3)....放(999,999),放(1000,1000)

是否会一直遍历地图结束,然后在执行最后一次放置(1000,1000)时将新的插入到头部?

OR

Map还有其他方法可以找到并替换重复的键吗?

3 个答案:

答案 0 :(得分:1)

第一种情况是正确的。

hashCode()为所有键返回相同哈希值的情况下。在java HashMap中,Key和Value都作为Map.Entry对象存储在存储桶中。在地图中执行第二次或更进一步的put()操作时,它将遍历所有元素以检查密钥是否已存在于Map中。如果未找到密钥,则新的密钥和值对将添加到链接列表中。如果在列表中找到Key,则更新该对的值。

有关java HashMap工作的详细说明:How HashMap works in Java

获取此示例代码并在调试模式下运行,并观察新Key和Value对如何插入Map中。

在课程中,您需要hashCode()(我们想要控制为Node生成哈希码的方式),toString()(只是为了输出Node值在SOUT中)和equals()(基于Node成员变量Integer的值来定义键的相等性,用于更新值。)使它工作的方法。

public class HashMapTest {

static class Node {
  Integer n;

  public Node(int n) {
    this.n = n;
  }

  @Override
  public int hashCode() {
    return n%3;
  }

  @Override
  public boolean equals(Object object) {
    Node node = (Node)object;
    return this.n.equals(node.n);
  }

  @Override
  public String toString() {
    return n.toString();
  }
}

  public static void main(String[] args) {
    Map<Node, String> map = new HashMap<>();
    for (int i = 0; i<6; i++) {
      map.put(new Node(i), ""+i);   // <-- Debug Point
    }
    map.put(new Node(0), "xxx");
  }                                 // <-- Debug Point
}

地图中的第一个3条目:(哈希码为n%3)

enter image description here

还有三个值:(哈希码是n%3)

enter image description here

现在不要对节点的排序感到困惑,我已经在java 1.8上执行了它们,而HashMap使用了TreeNode,这是一个根据代码文档实现的Red-Black树。 在不同版本的java中可能会有所不同。

现在让我们更新密钥0的价值:

enter image description here

答案 1 :(得分:1)

当哈希码相同时,哈希映射使用equals方法比较对象。

例如,假设你在哈希映射中放了一堆元素:

put(1000,1000), put(1,1), put( 2, 2), put ( 3,3 ) ....put(999,999)

然后你这样做:

put(1000,1000 )

1000已经在地图中,哈希码是相同的,它在equals方法上也是一样的,所以元素将被替换,不需要进一步迭代。

现在,如果你这样做:

put(1234, 1234)

1234尚未出现在地图中。由于固定的哈希码,所有元素都在链表中。哈希映射将迭代元素,使用equals进行比较。对于所有元素都将为false,将到达列表的末尾,并且将附加条目。

答案 2 :(得分:1)

JDK实现随时间而变化!

在JDK8中,如果hashCode()是常量值,则实现会创建一个树而不是链接列表,以防止DDOS攻击1