2011-11-09 18 views
19

私はキーと値のペアを格納する方法を探しています。私は双方向であるためにルックアップが必要ですが、同時に同じキーに対して複数の値を格納する必要があります。つまり、BidiMapのようなものですが、すべてのキーに複数の値がある可能性があります。たとえば、 "s1" - > 1、 "s2" - > 1、 "s3" - > 2のようなペアを保持できる必要があり、各キーに値をマッピングできるようにする必要があります。各値について、それに関連付けられたすべてのキーを取得します。Javaの双方向多値マップ

+3

キーごとに複数の値を持つ必要がありますが、例では複数の値を持つキーはありません。あなたはおそらくそれを明確にすべきです。あなたの例があなたの質問に合うなら、より良い答えを得るでしょう;-) – pushy

+0

http://www.jguru.com/faq/view.jsp?EID=1317828ここであなたはマルチマップを作成する方法を見つけることができます – maks

+0

@pushy、同じ問題、マップを逆にして、整数をキーの代わりに値として保持すると、1対多のマッピングが得られます。とにかく、訂正してくれてありがとう。 :) –

答えて

19

多対多関係のサポートが必要ですか?あなたが得ることができる最も近いのはGuavaの@MechkovのようなMultimapですが、具体的にはMultimapの組み合わせはMultimaps.invertFromです。 "BiMultimap"はまだ実装されていませんが、Google Guavaライブラリにこの機能をリクエストするan issueがあります。あなたの「BiMultimap」は不変定数に起こっている場合

  1. からMultimaps.invertFromImmutableMultimap/ImmutableListMultimap/ImmutableSetMultimapを(theese 3の各値を格納する別のコレクションを持っている)を使用します。この時点で

    あなたはいくつかのオプションがあります。いくつかのコード(例は私が開発するアプリから取られ、Enum sおよびSets.immutableEnumSetを使用しています):

    ​​
  2. あなたが本当にあなたのMultimapはが変更になりたい場合は、K-> VとV-の両方を維持するのは難しいだろう> K変形をkToVMultimapに変更する場合を除いて、invertFromとしてください。逆コピーをしたい場合は必ず kToVMultimapを修正しないでください。これは最適ではありませんが、この場合に行うべきです。

  3. (お使いの場合は、おそらく、ボーナスとして言及されていない):BiMapインタフェースと実装クラスはbiMap.inverse().inverse()BiMap<V, K>BiMap<K, V>からの眺めと自身を与える.inverse()方法があります。前に言及したthis issueが実行された場合、それはおそらく何か類似しているでしょう。

  4. (EDIT 2016年10月)あなたはまた、Guava 20で存在するであろうnew graph API使用することができます:全体として

    、共通します。

    • 有向グラフ
    • 無向グラフに関連付けられた値(重量、ラベル、等)しない/実行
    • グラフと
    • ノードおよび/またはエッジを:グラフは、以下の種類のグラフをサポート/実行
    • グラフは、そのノード/エッジ挿入順、ソート、又は順不同
    • ある平行なエッジ(平行なエッジを有するグラフは時々multigraphs呼ばれる)
    • グラフを許可しない自己ループ可能
-1

希望私はあなたの右

class A { 
    long id; 
    List<B> bs; 
} 

class B { 
    long id; 
    List<A> as; 
} 
2

2つのマップを持つと間違って何、キー - >値は、値 - >キーを得ましたか。

+3

私は、同じデータの2つのコピーを保存するとエラーが発生しやすくなると思いました。とにかく、私が見たすべてのコレクションの後、私はそれが最良のソリューションだと思っています。 –

+2

マップを同期させるためのラッパーを作成するだけです。 – Stefan

+10

私はこの答えによって裏付けられたアプローチを嫌います。おそらく、ホイールの再発明、道に沿った独自のバグの作成、スレッドの安全性などを含む多くのことが潜在的に間違っています。 – bacar

-3

GoogleのGuava MultiMapの実装は、私がこれらの目的で使っているものです。

Map<Key Collection<Values>> 

ここで、CollectionはArrayListなどです。これは、コレクションに格納された複数の値をキーにマップすることを可能にします。 これが役立つことを願っています!

+0

双方向ではありません。 – Stefan

1

私たちは以下のように原始的BiMulitMapを書くことができます。

import java.util.Collection; 

import com.google.common.collect.ArrayListMultimap; 
import com.google.common.collect.Multimap; 

public class BiMultiMap<K,V> { 

    Multimap<K, V> keyToValue = ArrayListMultimap.create(); 
    Multimap<V, K> valueToKey = ArrayListMultimap.create(); 

    public void putForce(K key, V value) { 
     keyToValue.put(key, value); 
     valueToKey.put(value, key); 
    } 

    public void put(K key, V value) { 
     Collection<V> oldValue = keyToValue.get(key); 
     if (oldValue.contains(value) == false) { 
      keyToValue.put(key, value); 
      valueToKey.put(value, key); 
     } 
    } 

    public Collection<V> getValue(K key) { 
     return keyToValue.get(key); 
    } 

    public Collection<K> getKey(V value) { 
     return valueToKey.get(value); 
    } 

    @Override 
    public String toString() { 
     return "BiMultiMap [keyToValue=" + keyToValue + ", valueToKey=" + valueToKey + "]"; 
    } 

} 

これは、双方向マルチマップの基本的なニーズに役立ちます。 KとVはhascodeとequalsメソッドを正しく実装する必要があることに注意してください。