Guava类库——BiMap和Multimap详解

前言

Guava 是一套来自 Google 的核心 Java 库,其中包括新的集合类型、不可变的集合、图库,以及并发、I/O、散列、缓存、基元、字符串等实用工具!

它更细粒度的提供了一些 jdk 没有的 api 和优化了一些操作,可以让你的代码更加优雅简洁高效。

它被广泛用于 Google 内部的大多数 Java 项目,也被许多其他公司广泛使用。

一、引入Guava

maven如下:

		<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>31.1-jre</version>
        </dependency>

二、BiMap

jdk 自带的 Map 其 key是唯一的,value 可以是重复的。

那能不能 key 和 value 都是唯一的呢,通过 key 可以找到 value,通过 value 也可以找到 key。

BiMap 就是这样的双向 map,且 key 和 value 都是唯一的。

注意:是在使用 BiMap 进行 put 时 value 不能重复,否则会抛出异常。

1.BiMap的创建和使用

		//创建一个BiMap
        BiMap<String,String> bigMap = HashBiMap.create();
        bigMap.put("a","1");
        bigMap.put("b","2");
		
        //通过key查找value
        System.out.println(bigMap.get("a"));//1
        //通过value查找key
        System.out.println(bigMap.inverse().get("2"));//b

2.HashMap转为BiMap

        Map<String, String> map = new HashMap<>();
        map.put("a","1");
        map.put("b","2");

        BiMap<String,String> bigMap = HashBiMap.create(map);
        System.out.println(bigMap);//{a=1, b=2}

3.使用forcePut覆盖value的值

        BiMap<String,String> bigMap = HashBiMap.create();
        bigMap.put("a","1");
        bigMap.put("b","2");
        System.out.println(bigMap);//{a=1, b=2}
        bigMap.forcePut("c","2");
        System.out.println(bigMap);//{a=1, c=2}

三、Multimap

代码里我们经常这样写 Map<k,List>,好像有点臃肿!另外我们还得判断 key 是否存在来决定是否 new 一个 List 出来,有点麻烦!更加麻烦的事情还在后头,比如遍历,比如删除。

所以Guava产生了Multimap来代替 Map<k,List> ,Multimap有点类似Map,但是Multimap中每个键可能与多个值相关联(即重复put相同的key时不会覆盖原来的)

1.Multimap的创建和使用

		Multimap<String,Integer> map = ArrayListMultimap.create();
        map.put("a",1);
        map.put("a",2);
        map.put("a",2);
        map.put("b",3);
        map.put("b",4);
		//{a=[1, 2, 2], b=[3, 4]}
        System.out.println(map);

2.获取值

(1) 根据key获取值

        Multimap<String,Integer> map = ArrayListMultimap.create();
        map.put("a",1);
        map.put("a",2);
        map.put("a",2);
        map.put("b",3);
        map.put("b",4);
        System.out.println(map);

        Collection<Integer> values = map.get("a");
        //[1, 2, 2]
        System.out.println(values);

(2) 获取所有的key和value

        Multimap<String,Integer> map = ArrayListMultimap.create();
        map.put("a",1);
        map.put("a",2);
        map.put("a",2);
        map.put("b",3);
        map.put("b",4);
        System.out.println(map);

        Set<String> keys = map.keySet();
        //[a, b]
        System.out.println(keys);
        Collection<Integer> values = map.values();
        //[1, 2, 2, 3, 4]
        System.out.println(values);

3. 获取所有的key的大小和value的大小
size()返回存储 Map 中实际值的数量,但keySet().size()返回不同键的数量。

        Multimap<String,Integer> map = ArrayListMultimap.create();
        map.put("a",1);
        map.put("a",2);
        map.put("a",2);
        map.put("b",3);
        map.put("b",4);
        System.out.println(map);

		//map 的大小
        int valuesSize = map.size();
        System.out.println(valuesSize);//5
        //去重后的键的数量        
        int keysSize = map.keySet().size();
        System.out.println(keysSize); //2

4. Multimap转Map

Multimap转Map后,这个Map支持remove和修改操作,但是不支持put和putAll操作

        Multimap<String,Integer> map = ArrayListMultimap.create();
        map.put("a",1);
        map.put("a",2);
        map.put("a",2);
        map.put("b",3);
        map.put("b",4);
        //{a=[1, 2, 2], b=[3, 4]}
        System.out.println(map);
        
        Map<String, Collection<Integer>> map1 = map.asMap();
        Collection<Integer> aValue = map1.get("a");
        aValue.add(999);
        //{a=[1, 2, 2, 999], b=[3, 4]}
        System.out.println(map1);

//       不能put会抛出异常        
//        Collection<Integer> collection=new ArrayList<>();
//        collection.add(88);
//        collection.add(88);
//        map1.put("c",collection);

5.遍历

        Multimap<String,Integer> map = ArrayListMultimap.create();
        map.put("a",1);
        map.put("a",2);
        map.put("a",2);
        map.put("b",3);
        map.put("b",4);
        //{a=[1, 2, 2], b=[3, 4]}
        System.out.println(map);

        for (Map.Entry<String,Integer> m: map.entries()) {
            System.out.println("key是:"+m.getKey()+" value是:"+m.getValue());
        }

输出:

{a=[1, 2, 2], b=[3, 4]}
key是:a value是:1
key是:a value是:2
key是:a value是:2
key是:b value是:3
key是:b value是:4

转换为Map后遍历:

        Multimap<String,Integer> map = ArrayListMultimap.create();
        map.put("a",1);
        map.put("a",2);
        map.put("a",2);
        map.put("b",3);
        map.put("b",4);
        //{a=[1, 2, 2], b=[3, 4]}
        System.out.println(map);

		Map<String, Collection<Integer>> map1 = map.asMap();
        for (Map.Entry<String,Collection<Integer>> m:map1.entrySet()) {
            System.out.println("key是:"+m.getKey()+" value是:"+m.getValue());
        }

输出:

{a=[1, 2, 2], b=[3, 4]}
key是:a value是:[1, 2, 2]
key是:b value是:[3, 4]

6.使用Multimap的优点

  • 在使用put()添加数据之前无需创建新的空集合
  • get() 方法不返回null,只返回一个空集合(可以不用像Map<k,List>获取值时去判空检查)
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Guava类库中的Table是一个双键的Map,可以理解为一个行列式的数据结构。 Table可以用来表示一个映射,其中每个键都有一个与之关联的值,而且这个键需要由两个参数来确定。在Table中,第一个键称为"行键",第二个键称为"列键",而对应的值称为"值"。 Table的实现方式可以看作是一个Map<RowKey, Map<ColumnKey, Value>>的嵌套结构,其中RowKey和ColumnKey分别表示行键和列键,Value表示对应的值。 Table提供了多种视图,包括行视图、列视图、单元格视图等,这些视图可以方便地进行表格的操作和查询。 下面是一个简单的示例代码: ```java Table<String, String, Integer> table = HashBasedTable.create(); table.put("row1", "col1", 1); table.put("row1", "col2", 2); table.put("row2", "col1", 3); table.put("row2", "col2", 4); System.out.println(table.get("row1", "col1")); // 输出1 System.out.println(table.row("row1")); // 输出{col1=1, col2=2} System.out.println(table.column("col1")); // 输出{row1=1, row2=3} System.out.println(table.cellSet()); // 输出[(row1,col1)=1, (row1,col2)=2, (row2,col1)=3, (row2,col2)=4] ``` 在上面的示例中,我们创建了一个Table对象,并往其中添加了四个元素。然后,我们分别通过get方法、row方法、column方法和cellSet方法获取了对应的视图,并输出了它们的内容。 需要注意的是,Table中的行键、列键和值都可以为null,但是在使用时需要特别注意空指针异常的问题。此外,Table中的行键和列键必须实现equals和hashCode方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值