Java Top.

使用Spring 5和Spring Boot 2开始,通过学习春天课程:

>>查看课程

1.概述

在本教程中,我们将探索处理A的可用选项地图用重复的键或换句话说,a地图允许存储单个键的多个值。

2.标准地图

Java有几个接口实现地图,每个人都有自己的特殊性。

然而,现有的Java核心地图实现都没有允许a地图处理单个键的多个值

正如我们所看到的,如果我们尝试插入两个相同键的值,则将存储第二个值,而第一个值将被丢弃。

它也将被退回(通过每个正确实施放(k键,v值)方法):

地图 map = new hashmap <>();asserthat(map.cput(“key1”,“value1”))。isequalto(null);Assertthat(Map.put(“key1”,“value2”))。isequalto(“value1”);asserthat(map.get(“key1”))。isequalto(“value2”);

我们如何达到所需的行为?

3.作为价值收集

显然,使用a收藏对于我们的每一个价值地图会做这项工作:

地图> map = new hashmap <>();列表列表= new arraylist <>();map.put(“key1”,list);map.get(“key1”)。添加(“value1”);map.get(“key1”)。添加(“value2”);asserthat(map.get(“key1”)。获得(0))。isequalto(“value1”);asserthat(map.get(“key1”)。获得(1))。isequalto(“value2”);

但是,这种冗长的解决方案具有多个缺点并且容易出错。它意味着我们需要实例化一个收藏对于每个值,请在添加或删除值之前检查其存在,当没有值左侧,单位单位,单独删除它。

来自Java 8我们可以利用计算()方法和改进它:

地图> map = new hashmap <>();map.computifabsent(“key1”,k  - >新arraylist <>())。添加(“value1”);map.computifabsent(“key1”,k  - >新arraylist <>())。添加(“value2”);asserthat(map.get(“key1”)。获得(0))。isequalto(“value1”);asserthat(map.get(“key1”)。获得(1))。isequalto(“value2”);

虽然这是值得了解的,但除非有一个非常好的原因,否则我们应该避免它,如限制性公司政策,防止我们使用第三方图书馆。

否则,在编写自己的自定义之前地图实施和重新发明轮子,我们应该在开箱即用的几个选项中进行选择。

4. Apache Commons Collections

照常,Apach.有解决问题的解决方案。

让我们首先导入最新版本常用系列(CC从现在开始):

<依赖>  org.apache.commons   Commons-CollectionS4   4.1  

4.1。多猿

org.apache.commons.collections4。多猿接口定义了一个映射,该映射包含每个键的值集合。

它由它实施org.apache.commons.collections4.map。多级美容类,自动处理引擎盖下的大部分水板:

multimap  map = new multivaluemap <>();map.put(“key1”,“value1”);Map.put(“key1”,“value2”);asserthat((collection )map.get(“key1”)).Contains(“value1”,“value2”);

虽然此类自CC 3.2以来可用,但它不是线程安全的, 和它已在CC 4.1中弃用。只有在无法升级到更新版本时,我们应该仅使用它。

4.2。多级图

继任者多猿是个org.apache.commons.collections4。多级图界面。它有多种准备使用的实现。

让我们看看如何将多个值存储到数组列表,保留重复项:

multivaluemap  map = new arraylistvaluedhashmap <>();map.put(“key1”,“value1”);Map.put(“key1”,“value2”);Map.put(“key1”,“value2”);asserthat((collection )map.get(“key1”)).ContainSexact(“value1”,“value2”,“value2”);

或者,我们可以使用一个hashset.,哪个丢弃重复:

multivaluemap  map = new hashsetvaluedhashmap <>();map.put(“key1”,“value1”);map.put(“key1”,“value1”);asserthat((collection )map.get(“key1”)).containsexactly(“value1”);

两者都是上面的实施不是线程安全的

让我们看看我们如何使用概念性亚洲北美普拉维拉斯图装饰者让他们不可变:

@Test(预期= UnsupportedOperationException.class)public voidedunmodifiaberlutivaludmap_wheninserting_thenthrownception(multivaluemap  map = new arraylistvaluedhashmap <>();map.put(“key1”,“value1”);Map.put(“key1”,“value2”);multivaluemap  immutablemap = multimaputils.unmodifiaberultiviveMap(地图);immutableMap.put(“key1”,“value3”);}

5.郭瓦多猿

番石榴是Java API的Google Core Libries。

com.google.common.collect。多猿自版本2.自版本以来,界面是最新版本是25,但自版本23之后,它已被分割在不同的分支中安卓25.0-JRE.25.0-Android.),我们仍然将为我们的示例使用版本23。

让我们从导入我们的项目上导入Guava:

<依赖>  com.google.guava   GUAVA   23.0  

Guava遵循自开始以来的多个实现的路径。

最常见的是com.google.common.collect。ArrayListMultimap.,它使用aHashmap.由AN。支持数组列表对于每个值:

multimap  map = arraylistmultimap.create();Map.put(“key1”,“value2”);map.put(“key1”,“value1”);asserthat((集合)map.get(“key1”)).ContainSexact(“value2”,“value1”);

一如既往,我们应该更喜欢Multimap接口的不可变实现:com.google.common.collect。ImmutablelisMultimap.com.google.common.collect。immutableetmultimap.

5.1。通用地图实现

当我们需要一个特定的时候地图实施,首先要做的是检查它是否存在,因为可能是番石榴已经实现了它。

例如,我们可以使用com.google.common.collect。linkedhashmultimap.,它保留了键和值的插入顺序:

multimap  map = linkedhashmultimap.create();map.put(“key1”,“value3”);map.put(“key1”,“value1”);Map.put(“key1”,“value2”);asserthat((collection )map.get(“key1”)).containsexact(“value3”,“value1”,“value2”);

或者,我们可以使用一个com.google.common.collect。特拉姆不同调,它以自然顺序迭代键和值:

multimap  map = tremultimap.create();map.put(“key1”,“value3”);map.put(“key1”,“value1”);Map.put(“key1”,“value2”);asserthat((collection )map.get(“key1”)).ContainSexact(“value1”,“value2”,“value3”);

5.2。锻造我们的习俗多猿

许多其他实现可用。

但是,我们可能想要装饰一个地图和/或一个列表尚未实现。

幸运的是,番石榴有一个工厂方法,允许我们这样做:multimap.newmultimap()

六,结论

我们已经看到了如何在所有主要现有方式中存储在地图中的密钥的多个值。

我们已经探索了Apache Commons集合和Guava最受欢迎的实现,这应该是在可能的情况下首选定制解决方案。

一如既往,可以使用完整的源代码在github上

Java底部

使用Spring 5和Spring Boot 2开始,通过学习春天课程:

>>查看课程
评论在本文上关闭!