如果我将相同的键多次传递给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是否像一个引用最后一个值的桶(但在内存中)?
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报头可以有相同的字段,…)
好运!:)
我总是用:
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");
}
HashMap<Emp, Emp> empHashMap = new HashMap<Emp, Emp>();
empHashMap.put(new Emp(1), new Emp(1));
empHashMap.put(new Emp(1), new Emp(1));
empHashMap.put(new Emp(1), new Emp());
empHashMap.put(new Emp(1), new Emp());
System.out.println(empHashMap.size());
}
}
class Emp{
public Emp(){
}
public Emp(int id){
this.id = id;
}
public int id;
@Override
public boolean equals(Object obj) {
return this.id == ((Emp)obj).id;
}
@Override
public int hashCode() {
return id;
}
}
OUTPUT : is 1
意思是哈希映射不允许重复,如果你已经正确地覆盖了equals和hashCode()方法。
HashSet也在内部使用HashMap,请参阅源文档
public class HashSet{
public HashSet() {
map = new 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"),它就变成不被引用的,因此有资格进行垃圾收集。