覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。 twitter: @yyoshikaw

com.google.common.collect.BiMap

Guavacom.google.common.collect.BiMapの利用サンプルです。
BiMapはいわゆる双方向Mapってやつです。
通常のMapはkeyからvalueを取得するという流れになりますが、BiMapではそれに加えて、valueからkeyを取得するということも可能です。
上記の件を実現するためにBiMapでは重複するvalueを登録することができません。

BiMapの特徴的なAPIとして以下があります

  • BiMap#inverse - 対象のMapのkeyとvalueを逆転させる
  • BiMap#forcePut - 値を強制登録する(指定のvalueが登録済みの場合、元のkeyとvalueの組み合わせは強制的に削除される)
  • BiMap#values - Mapに格納されているvalueを格納したSetを返却する

サンプルコードで試したのは以下の通りです。
(各種サンプルコードの前提として以下のBiMapが存在するものとします)

BiMap<Integer, String> map = HashBiMap.create();
map.put(1, "Koizumi");
map.put(2, "Abe");
map.put(3, "Aso");
map.put(4, "Hatoyama");
map.put(5, "Kan");


keyからvalueの取得

普通のMapの操作と同様です。getメソッドで取得可能です

■サンプル

String value1 = map.get(1);
String value2 = map.get(3);
System.out.println("key: " + 1 + " -> value: " + value1);
System.out.println("key: " + 3 + " -> value: " + value2);

■実行結果

key: 1 -> value: Koizumi
key: 3 -> value: Aso


valueからkeyを取得

inverseメソッドでkeyとvalueを逆転させたBiMapに対してgetを実行することで取得できます

■サンプル

int key1 = map.inverse().get("Abe");
int key2 = map.inverse().get("Hatoyama");
System.out.println("value: Abe -> key: " + key1);
System.out.println("value: Hatoyama -> key: " + key2);

■実行結果

value: Abe -> key: 2
value: Hatoyama -> key: 4


登録済みのvalueと同一のvalueはputでは登録できない

既に登録済みのvalueを再度BiMap#putで登録しようとするとIllegalArgumentExceptionがスローされます

■サンプル

try {
    map.put(6, "Koizumi");
} catch (IllegalArgumentException e) {
    e.printStackTrace();
}
System.out.println("key: " + 6 + " -> value: " + map.get(6));

■実行結果

java.lang.IllegalArgumentException: value already present: Koizumi
key: 6 -> value: null


値を強制登録する

BiMap#forcePutで登録を行うと、登録済みのvalueがある場合は元のkeyとvalueの組み合わせは強制的に削除されます

■サンプル

// "Koizumi" という value は key=1 に紐づけて登録がすでにされている状態
// put 操作では "Koizumi" というvalueは登録できない
map.forcePut(6, "Koizumi");
System.out.println("key: " + 1 + " -> value: " + map.get(1));
System.out.println("key: " + 6 + " -> value: " + map.get(6));

■実行結果

key: 1 -> value: null
key: 6 -> value: Koizumi


BiMap内の全valueを格納したSetの取得

BiMapはvalueも一意なのでvaluseメソッドで値のSetを取得することができます

■サンプル

Set<String> valuseSet = map.values();
System.out.println("values: " + valuseSet);

■実行結果

values: [Abe, Aso, Hatoyama, Kan, Koizumi]




試したソースコードの全体は以下です。

import java.util.Set;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;

public class BiMapClient {

    public static void main(String[] args) {

        BiMap<Integer, String> map = HashBiMap.create();
        map.put(1, "Koizumi");
        map.put(2, "Abe");
        map.put(3, "Aso");
        map.put(4, "Hatoyama");
        map.put(5, "Kan");

        // keyからvalueの取得(普通のMapと同じ操作)
        System.out.println("### BiMap#get");
        String value1 = map.get(1);
        String value2 = map.get(3);
        System.out.println("key: " + 1 + " -> value: " + value1);
        System.out.println("key: " + 3 + " -> value: " + value2);

        // valueからkeyを取得してみる(inverseでkeyとvalueを逆転させたBiMapに対してgetを実行)
        System.out.println("### BiMap#inverse");
        int key1 = map.inverse().get("Abe");
        int key2 = map.inverse().get("Hatoyama");
        System.out.println("value: Abe -> key: " + key1);
        System.out.println("value: Hatoyama -> key: " + key2);

        // 既に登録済みのvalueを再度BiMap#putで登録するとIllegalArgumentExceptionがスローされる
        System.out.println("### BiMap#put");
        try {
            map.put(6, "Koizumi");
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
        System.out.println("key: " + 6 + " -> value: " + map.get(6));

        // 既に登録済みのvalueでもBiMap#forcePutを使うと登録可能
        // 元々登録済みだったvalueとkeyの組合せの要素は削除される
        System.out.println("### BiMap#forcePut");
        map.forcePut(6, "Koizumi");
        System.out.println("key: " + 1 + " -> value: " + map.get(1));
        System.out.println("key: " + 6 + " -> value: " + map.get(6));

        // BiMapはvalueも一意なのでvaluseメソッドで値のSetを取得することができる
        System.out.println("### BiMap#values");
        Set<String> valuseSet = map.values();
        System.out.println("values: " + valuseSet);
    }
}