如果我将相同的键多次传递给HashMap的put方法,原始值会发生什么变化?如果值重复呢?我没找到任何关于这个的文件。

情况1:键的覆盖值

Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
System.out.println(mymap.get("1"));

我们得到的肯定不是1。

案例2:重复值

Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
// The following line was added:
mymap.put("1","one");
System.out.println(mymap.get("1"));

我们得到一个。

但是其他的值会怎样呢?我在给一个学生教授基础知识,有人问我这个问题。Map是否像一个引用最后一个值的桶(但在内存中)?


当前回答

它替换对应键的映射中现有的值。如果不存在同名的键,则使用所提供的值创建一个键。 例如:

Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","two");

输出 Key = "1", value = " 2 "

所以,之前的值会被覆盖。

其他回答

对于你的问题,地图是否像一个桶:不是。

它就像一个带有name=value对的列表,而name不需要是字符串(尽管它可以)。

要获取一个元素,您将键传递给get()方法,该方法返回给您赋值的对象。

Hashmap意味着如果您试图使用get方法检索对象,它不会将实际对象与您提供的对象进行比较,因为它需要遍历其列表并将您提供的键与当前元素进行比较()。

这将是低效的。相反,不管你的对象由什么组成,它都会从两个对象中计算一个所谓的hashcode并进行比较。比较两个int型对象要比比较两个完整的(可能非常复杂)对象容易得多。您可以将hashcode想象成具有预定义长度(int)的摘要,因此它不是唯一的,并且具有冲突。您可以在我插入链接的文档中找到hashcode的规则。

如果你想了解更多,你可能想看看javapractices.com和technofundo.com上的文章

问候

将指定值与此映射中的指定键关联。如果映射之前包含键的映射,则替换旧值。

是的,这意味着所有有值的1键都被最后一个添加的值覆盖,在这里你添加了“肯定不是一个”,所以它将只显示“肯定不是一个”。

即使您尝试使用循环显示,它也只会显示具有相同键的一个键和值。

根据定义,put命令替换映射中与给定键关联的前一个值(概念上类似于基本类型的数组索引操作)。

映射只是删除了对该值的引用。如果没有其他对象保存对该对象的引用,则该对象符合垃圾收集的条件。此外,Java返回与给定键相关的任何先前值(如果不存在则返回null),因此您可以确定那里有什么,并在必要时维护引用。

更多信息:HashMap文档

JDK中的映射并不用于在重复的键下存储数据。

在最好的情况下,新值将覆盖之前的值。 更糟糕的情况是异常(例如,当你试图收集它作为一个流):

没有重复:

Stream.of(“一”).collect(收藏者。toMap(x -> x, x -> x))

好的。你将得到:$2 ==> {one=one}

复制流:

流。“一个”,“不是一个”,“肯定不是一个”。toMap(x -> 1, x -> x))

Exception java.lang.IllegalStateException: Duplicate key 1 (attempted merging values one and not one) | at Collectors.duplicateKeyException (Collectors.java:133) | at Collectors.lambda$uniqKeysMapAccumulator$1 (Collectors.java:180) | at ReduceOps$3ReducingSink.accept (ReduceOps.java:169) | at Spliterators$ArraySpliterator.forEachRemaining (Spliterators.java:948) | at AbstractPipeline.copyInto (AbstractPipeline.java:484) | at AbstractPipeline.wrapAndCopyInto (AbstractPipeline.java:474) | at ReduceOps$ReduceOp.evaluateSequential (ReduceOps.java:913) | at AbstractPipeline.evaluate (AbstractPipeline.java:234) | at ReferencePipeline.collect (ReferencePipeline.java:578) | at (#4:1)

要处理重复的密钥-使用其他包,例如: https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html

有很多其他的实现处理重复的键。 这些是web所需要的(例如,重复的cookie密钥,Http报头可以有相同的字段,…)

好运!:)