在本篇文章中我们将介绍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. HAXM VT-X (与Hype-V冲突)

    之前一直使用vs emulator. 感觉性能各方面都比较好, 但在我更新完电脑后不知道什么原因各种起不来...  无奈之下想回到Google自带的模拟器. 然后发现intel haxm一直安装失败. ...

  2. es6+react环境搭建

    工具说明 Node Koa React Webpack 项目结构 - build 客户端代码的构建文件目录 - config 项目的配置文件 - docs 项目相关的文档目录 - lib 服务端库文件 ...

  3. 详解c++指针的指针和指针的引用

    展示一下使用指针的指针和指针的引用修改传递给方法的指针,以便更好的使用它.(这里说的指针的指针不是一个二维数组) 为什么需要使用它们 当我们把一个指针做为参数传一个方法时,其实是把指针的复本传递给了方 ...

  4. 判断 JS 中对象的类型

    1.typeof 形如 var x = "xx"; typeof x == 'string' typeof(x) 返回类型有:'undefined' “string” 'numbe ...

  5. 求解最大正方形面积 — leetcode 221. Maximal Square

    本来也想像园友一样,写一篇总结告别 2015,或者说告别即将过去的羊年,但是过去一年发生的事情,实在是出乎平常人的想象,也不具有代表性,于是计划在今年 6 月份写一篇 "半年总结" ...

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

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

  7. CSS 栅格布局

    bootstrap3.0教程之栅格系统原理(布局) http://www.jb51.net/css/152846.html [div+css]栅格化布局样式备用坑 http://www.0773lin ...

  8. apache 伪静态配置

    1 现配置站点, <VirtualHost *:80> //访问名称 ServerName my.seo_demo.com //项目地址 DocumentRoot "/Users ...

  9. 【转】VO BO PO 介绍

    原文链接:http://www.cnblogs.com/zander/archive/2012/08/11/2633344.html PO(persistant object)(个人理解:就是数据库模 ...

  10. Eclipse添加代码注释模板

    Eclipse支持我们自定义模板,比如文件的注释,类注释,函数注释等功能.eclipse自身有自带的模板,我们也可以自己定义.一次点击:windows->preference—>java- ...