在本篇文章中我们将介绍Guava集合中的BiMap这个接口.

com.google.common.collect

Interface BiMap<K,V>

BiMap接口的父接口是Map<K,V>。

而BiMap接口的实现类有:EnumBiMapEnumHashBiMapHashBiMapImmutableBiMap这四个。

我们可以通过源码可以看到BiMap接口的定义为:

@GwtCompatible
public interface BiMap<K,V>
extends Map<K,V>

如果我们用一句话来介绍BiMap的话,那就是:“它就是一个双向映射的Map”。我们可以通过key找到value,反之也能够根据value找到对应的key。

我们来面对一个比较常见的需求吧:

  对一个map进行逆转,原始的value作为key,key作为value。

好吧,这个需求其实并不是怎么的明确,没有说清楚是否需要考虑value重复的情况,我们假设不考虑value重复的情况,我们可以有下面的代码:

Map<String,String> britishToAmerican =   

Maps.newHashMap();  

britishToAmerican.put("aubergine","egglant");  

britishToAmerican.put("courgette","zucchini");  

britishToAmerican.put("jam","jelly");  

// Generic method to reverse map.  

public <S,T> Map<T,S> getInverseMap(Map<S,T> map) {  

Map<T,S> inverseMap = new HashMap<T,S>();  

for(Entry<S,T> entry: map.entrySet()) {  

inverseMap.put(entry.getValue(), entry.getKey());  

}  

return inverseMap;  

}

  正如上面所提到的,这样做能实现功能,但是有一些你要考虑的问题:

1)如何处理重复的value的情况,不考虑的话,那么反转的时候会覆盖前面的值

2)如果我们需要在反转的map中增加新的key呢?我们是否也需 要在原始的map中更新一个值呢!这个实在太烦了

在这种情况下,我们就可以使用BiMap.我们先来看看完成上面的功能的使用BiMap的代码:

BiMap<String,String> britishToAmerican = 

HashBiMap.create();

// Initialise and use just like a normal map

britishToAmerican.put("aubergine","egglant");

britishToAmerican.put("courgette","zucchini");

britishToAmerican.put("jam","jelly");

System.out.println(britishToAmerican.get

("aubergine")); // eggplant

BiMap<String,String> americanToBritish = 

britishToAmerican.inverse();

System.out.println(americanToBritish.get("eggplant")); // aubergine

System.out.println(americanToBritish.get("zucchini")); // courgette

很简单是吧,但是在使用BiMap的时候,需要注意几个地方:

BiMap强制其value的唯一性,如果发现违规则会抛出 IllegalArgumentException。

IllegalArgumentException。

britishToAmerican.put("pudding","dessert");

britishToAmerican.put("sweet","dessert"); // 

IllegalArgumentException.

但是如果你确实希望增加一个已经存在的值,那么可以使用forcePut 方法覆盖原有值。

britishToAmerican.put("pudding","dessert");

britishToAmerican.forcePut("sweet","dessert");  // Overwrites the previous entry

System.out.println(britishToAmerican.get("sweet")); // dessert

System.out.println(britishToAmerican.get("pudding")); // null

 另外一个关键点就是理解inverse方法,这个方法返回一个反转 后的BiMap,即key/value互相切换的映射。 这个反转的map并不是一个新的map,而是一个视图,这意味着, 你在这个反转后的map中的任何增删改操作都会影响原来的map。

americanToBritish.put("potato chips","crisps");

System.out.println(britishToAmerican.containsKey

("crisps")); // true

System.out.println(britishToAmerican.get("crisps")); 

// potato chips

  

BiMap的常用实现有:

HashBiMap: key 集合与 value 集合都有 HashMap 实现

EnumBiMap: key 与 value 都必须是 enum 类型

ImmutableBiMap: 不可修改的 BiMap

Guava集合-BiMap的更多相关文章

  1. java代码之美(7)---guava之Bimap

    guava之Bimap bimap的作用很清晰:它是一个一一映射,可以通过key得到value,也可以通过value得到key. 一.概述 1.bimap和普通HashMap区别 (1)在Java集合 ...

  2. Guava集合工具

    JDK提供了一系列集合类,如下所示,极大的方便了开发工作,并针对这些类提供了一个工具类java.util.Collections,Guava在此基础上添加了一些常用工具类方法,相比于java.util ...

  3. java代码(7) ---guava之Bimap

    guava之Bimap bimap的作用很清晰:它是一个——映射,可以通过key得到value,也可以通过value得到key 一.概述 1.bimap和普通HashMap区别 (1)在java集合类 ...

  4. Guava集合--Immutable(不可变)集合

    所谓不可变集合,顾名思义就是定义了之后不可修改的集合. 一.为什么要使用不可变集合 不可变对象有很多优点,包括: 当对象被不可信的库调用时,不可变形式是安全的: 不可变对象被多个线程调用时,不存在竞态 ...

  5. Guava集合--新集合类型

    Guava引入了很多JDK没有的.但我们发现明显有用的新集合类型.这些新类型是为了和JDK集合框架共存,而没有往JDK集合抽象中硬塞其他概念.作为一般规则,Guava集合非常精准地遵循了JDK接口契约 ...

  6. guava学习:guava集合类型-Bimap

    学习guava让我惊喜的第二个接口就是:Bimap BiMap是一种特殊的映射其保持映射,同时确保没有重复的值是存在于该映射和一个值可以安全地用于获取键背面的倒数映射. 最近开发过程中,经常会有这种根 ...

  7. Guava 集合框架

    在本系列中我们首先来学习一些Guava的集合框架,也就是这个package:com.google.common.collect 在这个包下面有一些通用的集合接口和一些相关的类.   集合类型: BiM ...

  8. guava学习:guava集合类型-table

    最近学习了下guava的使用,这里简单记录下一些常用并且使用的工具类把. 看到table的使用时候真的是眼前一亮,之前的代码中写过很多的Map<String,Map<String,Stri ...

  9. Guava学习笔记:Guava新增集合类型-Multiset

    Guava引进了JDK里没有的,但是非常有用的一些新的集合类型.所有这些新集合类型都能和JDK里的集合平滑集成.Guava集合非常精准地实现了JDK定义的接口.Guava中定义的新集合有: Multi ...

随机推荐

  1. jQuery EasyUI 1.3.4 API CHM版下载

    网盘下载

  2. Qt 学习笔记 TreeWidget 增删改

    在窗体上放一个TreeWidget控件和四个PushButton加一个Horizontal Spacer 布局如图 给树添加元素节点的方法和实现 .h文件 QTreeWidgetItem * AddT ...

  3. <实训|第十一天>学习一下linux中的进程,文件查找,文件压缩与IO重定向

    [root@localhost~]#序言 在今后的工作中,运维工程师每天的例行事务就是使用free -m,top,uptime,df -h...每天都要检查一下服务器,看看是否出现异常.那么今天我们就 ...

  4. bootstrap - typeahead自动补全插件

    $('#Sale').typeahead({ ajax: { url: '@Url.Action("../Contract/GetSale")', //timeout: 300, ...

  5. Python面试题 —— 计算列表中出现最多次的字符

    给你一个其中包含不同的英文字母和标点符号的文本,你要找到其中出现最多的字母,返回的字母必须是小写形式, 当检查最想要的字母时,不区分大小写,所以在你的搜索中 "A" == &quo ...

  6. 用 Linux自带的logrotate 来管理日志

    大家可能都有管理日志的需要,比如定时压缩日志,或者当日志超过一定大小时就自动分裂成两个文件等.最近就接到这样一个小任务.我们的程序用的是C语言,用log4cpp的library来实现日志记录.但是问题 ...

  7. 项目规范性检测工具Lint

    项目规范性检测工具lint.bat 一.Lint基本概念介绍 Android Lint是SDK Tools 16 (ADT 16)之后才引入的工具,通过它对Android工程源代码进行扫描和检查,可发 ...

  8. 网络功能虚拟化(NFV)

    你造什么是网络功能虚拟化(NFV)吗? NFV将网络功能整合到行业标准的服务器.交换机和存储硬件上,提供了优化的虚拟化数据平面,NFV通过服务器上运行的软件让管理员取代传统物理网络设备,并降低成本.能 ...

  9. 常用数据库高可用和分区解决方案(2) — MongoDB篇

    MongoDB是当前比较流行的文档型数据库,其拥有易使用.易扩展.功能丰富.性能卓越等特性.MongoDB本身就拥有高可用及分区的解决方案,分别为副本集(Replica Set)和分片(shardin ...

  10. JavaIO流文件的操作总结

    IO流的分类 1.根据数据的流向: 输入流:用来读数据,如从外界设备读数据到内存中: 输出流:用来写数据,如从内存输出数据到外界存储设备: 2.根据数据流的格式: 字节流:一般用于声音或者秃瓢等二进制 ...