有时我们不仅要以Key来获取Value,还要通过Value值获取Key,BidiMap实现了Key和Value的双向查找,但此时Key和Value必须一一对应。不可一个Key对应多个Value。
Maven项目使用前,请加入commons-collections依赖在你的项目pom.xml中。
下面为一个简单的应用,inverseBidiMap()方法的使用来实现反向获取:
import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.bidimap.DualHashBidiMap;
public class BidMapExample {
public static void main(String[] args) {
/*
* DualHashBidiMap stores keys and values in two HashMap instances.
* One HashMap stores keys as keys and values as values, and the
* other HashMap stores the inverse-values as keys and keys as values.
*/
BidiMap bidiMap = new DualHashBidiMap( );
bidiMap.put( "il", "Illinois" );
bidiMap.put( "az", "Arizona" );
bidiMap.put( "va", "Virginia" );
// Retrieve the key with a value via the inverse map
String vaAbbreviation=(String)bidiMap.inverseBidiMap().get("Virginia");
System.out.println(vaAbbreviation);
// Retrieve the value from the key
String illinoisName = (String)bidiMap.get( "il" );
System.out.println(illinoisName);
}
}
输出为:va
Illinois
下面介绍一个ISO国家编码和国家名称之间的互相获取的应用(如us是United States的国家编码):
import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.bidimap.DualHashBidiMap;
public class BidiMapExample {
private BidiMap countryCodes = new DualHashBidiMap( );
public static void main(String[] args) {
BidiMapExample example = new BidiMapExample( );
example.start( );
}
private void start(){
populateCountryCodes( );
String countryName=(String)countryCodes.get("tr");
System.out.println( "Country Name for code 'tr': " + countryName );
String countryCode=(String)countryCodes.inverseBidiMap().get("Uruguay");
System.out.println( "Country Code for name 'Uruguay': " + countryCode );
countryCode = (String) countryCodes.getKey("Ukraine");
System.out.println( "Country Code for name 'Ukraine': " + countryCode );
}
private void populateCountryCodes( ) {
countryCodes.put("to","Tonga");
countryCodes.put("tr","Turkey");
countryCodes.put("tv","Tuvalu");
countryCodes.put("tz","Tanzania");
countryCodes.put("ua","Ukraine");
countryCodes.put("ug","Uganda");
countryCodes.put("uk","United Kingdom");
countryCodes.put("um","USA Minor Outlying Islands");
countryCodes.put("us","United States");
countryCodes.put("uy","Uruguay");
}
}
输出:
Country Name for code 'tr': Turkey
Country Code for name 'Uruguay': uy
Country Code for name 'Ukraine': ua
BidiMap是一对一的Map,新加入的相同key值的value,新加入的value会替换原有的value(同Map)同时,值得注意的是,加入的相同的value值时,原先的Key值也会被替换,如下例所示:
mport org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.bidimap.DualHashBidiMap;
public class BidiMapExample {
public static void main(String[] args) {
BidiMap bidiMap = new DualHashBidiMap( );
// Insert initial content { "one:"red", "two":"green", "three":"blue" }
bidiMap.put("one","red");
bidiMap.put("two","green");
bidiMap.put("three","blue");
// replace "one" key entry
bidiMap.put("one","black");
// replace "green" value entry
bidiMap.put("five","green");
// Contents are now { "one":"black", "three":"blue", "five":"green" }
/*
* 1.Changing key "one," value "black" replaces the original key "one,"
* value "red" because the key is duplicated; this behavior is consistent
* with a normal implementation of Map. The difference in a BidiMap is that
* when adding key "five,"value "green" to a BidiMap, the previous key "two,"
* value "green" is replaced with a new entry because "green" is a duplicate
* value.Bidirectional access to keys by value is only possible if keys and
* values form two unique sets.
* 2.There are three implementations of the BidiMap interface: DualHashBidiMap,
* DualTreeBidiMap, and TreeBidiMap. A DualHashBidiMap is the simplest option,
* storing keys and values in two separate instances of HashMap. When a value is
* requested by key, one HashMap is consulted, and when a key is requested by value,
* the inverse HashMap is consulted. The DualHashMap is likely to be your
* implementation of choice if it is not important to keep track of the insertion
* order; it has a straightforward implementation using the familiar HashMap.
* 3.If you need to preserve the order of insertion, a DualTreeBidiMap uses two
* separate TreeMap instances to hold the regular and inverse mappings. This
* implementation implements the SortedMap interface that keeps track of the order
* of insertion and provides subMap( ), headMap( ), and tailMap( ) methods.
* A third implementation, TreeBidiMap, implements BidiMap without maintaining
* two internal storage maps. Instead, TreeBidiMap stores nodes in a red-black tree,
* identifying each node as both a key and a value; it costs twice as much to put( )
* into a TreeBidiMap, but this implementation comes in handy if you are worried about
* memory consumption—it does not need to store each key and value twice in two maps.
*/
}
}