web-dev-qa-db-ja.com

Javaコレクション-一意のキーと一意の値

キーに基づいて値をルックアップできるコレクションが必要です。その逆も可能です。すべての値に対して1つのキーがあり、すべてのキーに対して1つの値があります。これを行うすぐに使用できるデータ構造はありますか?

28
javacavaj

BiMap from Google Guava あなたに合っているようです。

バイマップ(または「双方向マップ」)は、その値とそのキーの一意性を保持するマップです。この制約により、バイマップは「インバースビュー」をサポートできます。これは、このバイマップと同じエントリを含むが、キーと値が逆になっている別のバイマップです。

または BidiMap from Apache Commons Collections

キーと値の間の双方向ルックアップを可能にするマップを定義します。

この拡張されたMapは、キーが値をルックアップでき、値が同じように簡単にキーをルックアップできるマッピングを表します。このインターフェースはMapを拡張するため、マップが必要な場所であればどこでも使用できます。インターフェースは逆マップビューを提供し、BidiMapの両方向へのフルアクセスを可能にします。

33
Michael Myers

BiMap from Eclipse Collections (以前のGSCollections)を使用できます。

BiMapは、ユーザーが両方向からルックアップを実行できるようにするマップです。 BiMapのキーと値はどちらも一意です。

主な実装はHashBiMapです。

inverse()

BiMap.inverse()は、キータイプと値タイプの位置が入れ替わっているビューを返します。

_MutableBiMap<Integer, String> biMap =
  HashBiMap.newWithKeysValues(1, "1", 2, "2", 3, "3");
MutableBiMap<String, Integer> inverse = biMap.inverse();
Assert.assertEquals("1", biMap.get(1));
Assert.assertEquals(1, inverse.get("1"));
Assert.assertTrue(inverse.containsKey("3"));
Assert.assertEquals(2, inverse.put("2", 4));
_

put()

MutableBiMap.put()は、重複する値が追加されたときにスローされることを除いて、通常のマップではMap.put()のように動作します。

_MutableBiMap<Integer, String> biMap = HashBiMap.newMap();
biMap.put(1, "1"); // behaves like a regular put()
biMap.put(1, "1"); // no effect
biMap.put(2, "1"); // throws IllegalArgumentException
_

forcePut()

これはMutableBiMap.put()のように動作しますが、キーと値のペアをマップに配置する前に、同じ値のマップエントリをサイレントに削除します。

_MutableBiMap<Integer, String> biMap = HashBiMap.newMap();
biMap.forcePut(1, "1"); // behaves like a regular put()
biMap.forcePut(1, "1"); // no effect
biMap.put(1, "2"); // replaces the [1,"1"] pair with [1, "2"]
biMap.forcePut(2, "2"); // removes the [1, "2"] pair before putting
Assert.assertFalse(biMap.containsKey(1));
Assert.assertEquals(HashBiMap.newWithKeysValues(2, "2"), biMap);
_

注:私はEclipseコレクションのコミッターです。

8
Craig P. Motlin

受け入れられた回答はBiMapに言及していますが、Google Guavaライブラリでは より最新 になっています。

_BiMap<K, V>_は_Map<K, V>_です

  • inverse()で「逆」_BiMap<V, K>_を表示できます
  • 値が一意であることを保証し、values()Setにします

したがって、次のようなコードになってしまう可能性があります。

_final BiMap<String, Integer> biMap = HashBiMap.create();
biMap.put("Word", 1);
biMap.put("alpha", 2);
System.out.println(biMap.get("Word")); // prints 1
System.out.println(biMap.inverse().get(1)); // prints Word
_

このオブジェクトに関するいくつかの注意事項:

1
Makoto