如果我将相同的键多次传递给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是否像一个引用最后一个值的桶(但在内存中)?


当前回答

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

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

其他回答

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

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

更多信息:HashMap文档

你可以在map# put(K, V)的javadoc中找到答案(它实际上会返回一些东西):

public V put(K key, V value) Associates the specified value with the specified key in this map (optional operation). If the map previously contained a mapping for this key, the old value is replaced by the specified value. (A map m is said to contain a mapping for a key k if and only if m.containsKey(k) would return true.) Parameters: key - key with which the specified value is to be associated. value - value to be associated with the specified key. Returns: previous value associated with specified key, or null if there was no mapping for key. (A null return can also indicate that the map previously associated null with the specified key, if the implementation supports null values.)

如果你在调用mymap时不分配返回值。Put ("1", "a string"),它就变成不被引用的,因此有资格进行垃圾收集。

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

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

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

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

我总是用:

HashMap<String, ArrayList<String>> hashy = new HashMap<String, ArrayList<String>>();

如果我想把多个东西应用到一个标识键上。

public void MultiHash(){
    HashMap<String, ArrayList<String>> hashy = new HashMap<String, ArrayList<String>>();
    String key = "Your key";

    ArrayList<String> yourarraylist = hashy.get(key);

    for(String valuessaved2key : yourarraylist){
        System.out.println(valuessaved2key);
    }

}

你可以做一些这样的事情,为自己创建一个迷宫!

public void LOOK_AT_ALL_THESE_HASHMAPS(){
    HashMap<String, HashMap<String, HashMap<String, HashMap<String, String>>>> theultimatehashmap = new HashMap <String, HashMap<String, HashMap<String, HashMap<String, String>>>>();
    String ballsdeep_into_the_hashmap = theultimatehashmap.get("firststring").get("secondstring").get("thirdstring").get("forthstring");
}

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报头可以有相同的字段,…)

好运!:)