好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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测试数据puteIfAbsent( "key1" , k -> new ArrayList<>()).add( "value1" );

map测试数据puteIfAbsent( "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测试数据mons</ groupId >

   < artifactId >commons-collections4</ artifactId >

   < version >4.1</ version >

</ dependency >

3.1 MutiMap

org.apache测试数据mons.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测试数据mons.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

查看更多关于Java如何在Map中存放重复key的详细内容...

  阅读:61次