Java在Map中存放重复key

Java在Map中存放重复key

1.概述

本文介绍几种处理Map中一个key对多个value的方法。在JDK标准Map实现中当我们尝试在一个key下插入多个value,那么后续的value会覆盖前面的value。

Map map = new HashMap<>();

assertThat(map.put("key1", "value1")).isEqualTo(null);

assertThat(map.put("key1", "value2")).isEqualTo("value1");

assertThat(map.get("key1")).isEqualTo("value2");

2.将集合作为Value

当要处理一个key对多个value的情况,可以将所有value存放在一个集合中。

Map> map = new HashMap<>();

List list = new ArrayList<>();

map.put("key1", list);

map.get("key1").add("value1");

map.get("key1").add("value2");

assertThat(map.get("key1").get(0)).isEqualTo("value1");

assertThat(map.get("key1").get(1)).isEqualTo("value2");

这种方式处理有多种缺点并且容易产生错误。我们需要为每个key创建一个集合,同时检查集合是否存在并添加或删除值,在Java 8中可以利用compute()方法来简化代码。

Map> map = new HashMap<>();

map.computeIfAbsent("key1", k -> new ArrayList<>()).add("value1");

map.computeIfAbsent("key1", k -> new ArrayList<>()).add("value2");

assertThat(map.get("key1").get(0)).isEqualTo("value1");

assertThat(map.get("key1").get(1)).isEqualTo("value2");

3.使用Apache Commons Collections

添加依赖

org.apache.commons

commons-collections4

4.1

3.1 MutiMap

org.apache.commons.collections4.MultiMap接口定义了一个Map,每个key对应一个集合。

MultiMap map = new MultiValueMap<>();

map.put("key1", "value1");

map.put("key1", "value2");

assertThat((Collection) map.get("key1"))

.contains("value1", "value2");

这个类非线程安全,4.1版本中已经废弃。

3.2 MultiValuedMap

org.apache.commons.collections4.MultiValuedMap这个接口有多种实现,如ArrayListValuedHashMap与HashSetValuedHashMap。

使用方式如下:

MultiValuedMap map = new ArrayListValuedHashMap<>();

map.put("key1", "value1");

map.put("key1", "value2");

map.put("key1", "value2");

assertThat((Collection) map.get("key1"))

.containsExactly("value1", "value2", "value2");

MultiValuedMap map = new HashSetValuedHashMap<>();

map.put("key1", "value1");

map.put("key1", "value1");

assertThat((Collection) map.get("key1"))

.containsExactly("value1");

若不希望value重复那么可以使用HashSetValuedHashMap

MultiValuedMap map = new HashSetValuedHashMap<>();

map.put("key1", "value1");

map.put("key1", "value1");

assertThat((Collection) map.get("key1"))

.containsExactly("value1");

但ArrayListValuedHashMap,HashSetValuedHashMap及HashSetValuedHashMap都不是线程安全的。为了线程安全可以使用UnmodifiableMultiValuedMap。

@Test(expected = UnsupportedOperationException.class)

public void givenUnmodifiableMultiValuedMap_whenInserting_thenThrowingException() {

MultiValuedMap map = new ArrayListValuedHashMap<>();

map.put("key1", "value1");

map.put("key1", "value2");

MultiValuedMap immutableMap =

MultiMapUtils.unmodifiableMultiValuedMap(map);

immutableMap.put("key1", "value3");

}

4.Guava Multimap

com.google.guava

guava

23.0

4.1 LinkedHashMultimap

这个类按插入顺序存放插入元素

Multimap map = LinkedHashMultimap.create();

map.put("key1", "value3");

map.put("key1", "value1");

map.put("key1", "value2");

assertThat((Collection) map.get("key1"))

.containsExactly("value3", "value1", "value2");

4.2 TreeMultimap

这个类按可以按自然序访问插入的元素

Multimap map = TreeMultimap.create();

map.put("key1", "value3");

map.put("key1", "value1");

map.put("key1", "value2");

assertThat((Collection) map.get("key1"))

.containsExactly("value1", "value2", "value3");

5.自定义MultiMap

如果使用Guava,那么还可以使用Multimap.newMultimap()来定制我们的Map。

6.总结

一对多思路就是通过集合来存储元素,guava和apache collection为我们提供了现成的工具,如果想自定义还可以使用guava提供的扩展方法来实现。

7 原文地址

https://www.baeldung.com/java-map-duplicate-keys

相关星际资讯

省电模式如何轻松退出?智能设备使用指南与小贴士
中兴Blade A601(全网通)
365wm完美体育官网

中兴Blade A601(全网通)

🕒 07-31 👁️ 6821
輕鬆駕馭,月季嫁接全攻略——提升成活率,多彩花開的祕密