在前面的《[Guava學習之Multimap](http://www.iteblog.com/archives/488 "Guava學習之Multimap")》文章中我們談到了Guava類庫中的Multimap,其特點是存在在Multimap中的鍵值對可以不唯一;而我們又知道,在Java集合類庫中有個Map,它的特點是存放的鍵(Key)是唯一的,而值(Value)可以不唯一,如果我們需要鍵(Key)和值(Value)都唯一,該怎么實現?這就是今天要談的BiMap結構。
在過去,如果需要將Map結構中的鍵值對反轉(也就是key->value轉變成value->key),這時候我們需要定義兩個Map數據結構來存儲。但,如果Map中存在多個value相同的元素會發生什么情況呢?這時候添加進去的key將會覆蓋先前加進去的key。如下所示:
> k1->v1,k2->v2,k3->v3,k4->v1如果我們需要反轉key和Value將會變成v1->k4,v2->k2,v3->k3,細心的人會發現,怎么少了一項,這是為什么呢?因為k1->v1和k4->v1反轉之后變成v1->k1和v1->k4,但由于Map的特點v1->k4將覆蓋先前的v1->k1。
這就是BiMap用武之地了!BiMap<K, V>是Map<K, V>類型的數據類型(因為BiMap實現了java.util.Map接口,注意和Multimap的區別,Multimap沒實現Map的接口)。它的特點是它的 value 和它 key 一樣也是不可重復的,換句話說它的 key 和 value 是等價的。如果你往 BiMap 的 value 里面放了重復的元素,就會得到 IllegalArgumentException。如下:
~~~
BiMap<String, String> upperToSmall = HashBiMap.create();
upperToSmall.put("A", "a");
upperToSmall.put("B", "b");
upperToSmall.put("C", "c");
System.out.println(upperToSmall.get("A"));
~~~
將得到一個存放key和value唯一的結構,如果在上述代碼加入一行
~~~
upperToSmall.put("D", "c");
~~~
則程序將拋出以下異常
> Exception in thread “main” java.lang.IllegalArgumentException: value already present: c
at com.google.common.collect.HashBiMap.put(HashBiMap.java:241)
at com.google.common.collect.HashBiMap.put(HashBiMap.java:218)
at com.wyp.test.testFiles(test.java:142)
at com.wyp.test.main(test.java:153)
這是因為BiMap的強制唯一性:BiMap強制其value的唯一性,如果發現違規則會拋出 IllegalArgumentException。是不是當添加的value先前已經有了就不能添加了呢?答案是否,我們可以利用BiMap提供的BiMap.forcePut(key, value)來實現。那如何通過BiMap將key和value反轉呢?很簡單,代碼如下:
~~~
BiMap<String, String> smallToUpper = upperToSmall.inverse();
System.out.println(smallToUpper.get("a")); //
~~~
這樣就實現了鍵值反轉!需要注意的是,inverse方法返回一個反轉后的BiMap,即key/value互相切換的映射。這個反轉的map并不是一個新的map(upperToSmall == upperToSmall.inverse().inverse()),而是一個視圖,這意味著,你在這個反轉后的map中的任何增刪改操作都會影響原來的map。
BiMap的常用實現有:
1. HashBiMap: key 集合與 value 集合都有 HashMap 實現
1. EnumBiMap: key 與 value 都必須是 enum 類型
1. ImmutableBiMap: 不可修改的 BiMap
轉載請注明: 轉載自[過往記憶(http://www.iteblog.com/)](http://www.iteblog.com/)
本文鏈接地址:?[Guava學習之BiMap(http://www.iteblog.com/archives/501)](http://www.iteblog.com/archives/501)