服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Java如何在Map中存放重复key

Java如何在Map中存放重复key

2022-12-02 17:23FserSuN Java教程

这篇文章主要介绍了Java如何在Map中存放重复key,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

如何在Map中存放重复key

1.概述

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

?
1
2
3
4
Map<String, String> 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存放在一个集合中。

?
1
2
3
4
5
6
7
8
Map<String, List<String>> map = new HashMap<>();
List<String> 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()方法来简化代码。

?
1
2
3
4
5
6
Map<String, List<String>> 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

添加依赖

?
1
2
3
4
5
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-collections4</artifactId>
  <version>4.1</version>
</dependency>

3.1 MutiMap

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

?
1
2
3
4
5
MultiMap<String, String> map = new MultiValueMap<>();
map.put("key1", "value1");
map.put("key1", "value2");
assertThat((Collection<String>) map.get("key1"))
  .contains("value1", "value2");

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

3.2 MultiValuedMap

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

使用方式如下:

?
1
2
3
4
5
6
7
8
9
10
11
MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
map.put("key1", "value1");
map.put("key1", "value2");
map.put("key1", "value2");
assertThat((Collection<String>) map.get("key1"))
  .containsExactly("value1", "value2", "value2");
MultiValuedMap<String, String> map = new HashSetValuedHashMap<>();
map.put("key1", "value1");
map.put("key1", "value1");
assertThat((Collection<String>) map.get("key1"))
  .containsExactly("value1");

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

?
1
2
3
4
5
MultiValuedMap<String, String> map = new HashSetValuedHashMap<>();
map.put("key1", "value1");
map.put("key1", "value1");
assertThat((Collection<String>) map.get("key1"))
  .containsExactly("value1");

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

?
1
2
3
4
5
6
7
8
9
@Test(expected = UnsupportedOperationException.class)
public void givenUnmodifiableMultiValuedMap_whenInserting_thenThrowingException() {
    MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
    map.put("key1", "value1");
    map.put("key1", "value2");
    MultiValuedMap<String, String> immutableMap =
      MultiMapUtils.unmodifiableMultiValuedMap(map);
    immutableMap.put("key1", "value3");
}

4.Guava Multimap

?
1
2
3
4
5
<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>23.0</version>
</dependency>

4.1 LinkedHashMultimap

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

?
1
2
3
4
5
6
Multimap<String, String> map = LinkedHashMultimap.create();
map.put("key1", "value3");
map.put("key1", "value1");
map.put("key1", "value2");
assertThat((Collection<String>) map.get("key1"))
  .containsExactly("value3", "value1", "value2");

4.2 TreeMultimap

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

?
1
2
3
4
5
6
Multimap<String, String> map = TreeMultimap.create();
map.put("key1", "value3");
map.put("key1", "value1");
map.put("key1", "value2");
assertThat((Collection<String>) map.get("key1"))
  .containsExactly("value1", "value2", "value3");

5.自定义MultiMap

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

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

Map出现重复Key值叠加到上一个key中

Map出现重复Key值将下一个key值叠加在上一个key值中

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
List<Map<String, Object>> list = new ArrayList<>();
     //模拟数据库数据
     for (int i = 0; i < 10; i++) {
         Map<String, Object> map = new HashMap<>();
         map.put("id", i);
         map.put("name", "张三" + i);
         if (i < 10 - 1) {
             map.put("pid", 2);
         } else {
             map.put("pid", 3);
         }
         list.add(map);
     }
     //运用map中的containsKey方法
     Map<String, Object> map1 = new HashMap<>();
     for (Map map2 : list) {
         List<Object> list1 = new ArrayList<>();
         String pid = map2.get("pid") + "";
         //如果是重复的那么就进行叠加操作
         if (map1.containsKey(pid)) {
             list1 = (List<Object>) map1.get(pid);
         }
         list1.add(map2);
         map1.put(map2.get("pid") + "", list1);
     }
     System.out.println(map1);       
 }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。 

原文链接:https://blog.csdn.net/Revivedsun/article/details/96225010

延伸 · 阅读

精彩推荐