一、概述
Java中的Map是一种键值对存储结构,它允许使用一个key访问对应的value。然而,在某些情况下,我们需要存储相同的key,这时就需要考虑如何处理相同key之间的value。
二、HashMap
Java中的HashMap是一种非同步的、快速的键值对集合,它允许存储其中相同的key。在HashMap中,相同key的value会被覆盖,即最后一次put进去的value会成为该key对应的值。下面是一个使用HashMap的例子:
Map<String, String> map = new HashMap<>(); map.put("key1", "value1"); map.put("key2", "value2"); map.put("key3", "value3"); map.put("key1", "value4");
在上述例子中,因为第一次和第四次put的key都是"key1",所以最终该key对应的值为"value4"。值得注意的是,在HashMap中,如果key为null,则它的value会覆盖之前存储的null值。
三、LinkedHashMap
LinkedHashMap是HashMap的一个子类,它保持了插入顺序,即当我们遍历Map时,它会按照插入的顺序返回key-value对。该类也允许存储相同的key。当我们使用LinkedHashMap来存储相同key的值时,最终该key对应的value会是所有插入的值的列表。下面是一个使用LinkedHashMap的例子:
Map<String, List<String>> map = new LinkedHashMap<>(); map.computeIfAbsent("key1", k -> new ArrayList<>()).add("value1"); map.computeIfAbsent("key2", k -> new ArrayList<>()).add("value2"); map.computeIfAbsent("key3", k -> new ArrayList<>()).add("value3"); map.computeIfAbsent("key1", k -> new ArrayList<>()).add("value4");
在上述例子中,我们使用了computeIfAbsent方法来处理相同的key。当key在Map中不存在时,computeIfAbsent方法使用提供的Function计算value并将其与key关联。当key已存在时,该方法返回与key关联的value。因此,在上述例子中,使用computeIfAbsent方法后,"key1"对应的值变成了["value1", "value4"]。
四、ConcurrentHashMap
ConcurrentHashMap是一种线程安全的HashMap,它的put方法是线程安全的。当我们在多线程环境下使用HashMap时,会出现数据竞争的问题,导致数据被覆盖或者遗漏。使用ConcurrentHashMap可以解决这个问题。当多个线程同时向ConcurrentHashMap中put相同的key-value对时,它不仅不会出现数据竞争,而且会保证所有key-value都能被正确地存储。下面是一个使用ConcurrentHashMap的例子:
ConcurrentMap<String, String> map = new ConcurrentHashMap<>(); map.put("key1", "value1"); map.put("key2", "value2"); map.put("key3", "value3"); map.put("key1", "value4");
在上述例子中,当多个线程同时调用put方法时,ConcurrentHashMap会保证所有key-value都能被正确地存储。
五、TreeMap
TreeMap是一种基于红黑树实现的有序Map,它按照key的自然顺序进行排序。当我们需要使用有序的Map时,可以使用TreeMap。在TreeMap中,相同的key会被覆盖,即最后一次put进去的value会成为该key对应的值。下面是一个使用TreeMap的例子:
Map<String, String> map = new TreeMap<>(); map.put("key1", "value1"); map.put("key2", "value2"); map.put("key3", "value3"); map.put("key1", "value4");
在上述例子中,因为第一次和第四次put的key都是"key1",所以最终该key对应的值为"value4"。