Java如何在Map中存放重复key
如何在Map中存放重复key
1.概述
本文介绍几种处理Map中一个key对多个value的方法。在JDK标准Map实现中当我们尝试在一个key下插入多个value,那么后续的value会覆盖前面的value。
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存放在一个集合中。
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()方法来简化代码。
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
添加依赖
<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对应一个集合。
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。
使用方式如下:
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
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。
@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
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>23.0</version> </dependency>
4.1 LinkedHashMultimap
这个类按插入顺序存放插入元素
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
这个类按可以按自然序访问插入的元素
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值中
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); }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
eclipse/IDEA配置javafx项目步骤(图文教程)
这篇文章主要介绍了eclipse/IDEA配置javafx项目步骤(图文教程),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-03-03基于Spring Data的AuditorAware审计功能的示例代码
这篇文章主要介绍了基于Spring Data的AuditorAware审计功能的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-03-03Spring Boot下如何自定义Repository中的DAO方法
这篇文章主要介绍了Spring Boot下如何自定义Repository中的DAO方法,需要的朋友可以参考下2017-06-06解决报错:java.lang.IllegalStateException: Failed to&nb
在项目开发中,可能会遇到Elasticsearch启动报错的问题,原因可能包括版本不一致、端口配置错误、配置文件不匹配及服务未启动等,解决方法包括检查进程、重启服务等,这些经验可以帮助开发者快速定位问题并解决,保证项目顺利运行2024-10-10SpringBoot整合mybatisplus和druid的示例详解
这篇文章主要介绍了SpringBoot整合mybatisplus和druid的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2023-08-08
最新评论