ネストされたコレクションをよりエレガントに処理する方法はありますか?


8

私の質問はむしろデザインの質問です。私のプログラムでは、次のようなデータ構造に到達しました。

private ConcurrentHashMap<A, ConcurrentHashMap<B, ConcurrentHashMap<Integer, C>>> services  = new ConcurrentHashMap<A, ConcurrentHashMap<B, ConcurrentHashMap<Integer, C>>>();

そのようなデータ構造をよりエレガントに処理する方法はありますか?ありがとう!

edit:A、B、Cはビジネスクラスです。Aインスタンスは(関連付けとして)多くのBを「持つ」ことができ、Bは多数のマッピングを「持つ」ことができますInteger-C。


どのような種類がありABC?そこにあるマップの3レベルのネストの意味を理解できたら、答えるのは簡単でしょう。
dasblinkenlight 2012年

1
ドメインについて何かを知らなければ、私には一般的な解決策はないと思います。マップの使用方法によっては、1つ以上のマップを特定のプロパティセットをエクスポートするクラスに置き換えることを検討する場合があります。
アーネストフリードマンヒル

4
ばかばかしいデータ構造ではなく、動作をカプセル化するオブジェクトの使用を検討してください。これらのマップはそれぞれ、特定のオブジェクトにラップする必要があります。

余談ですがConcurrentHashMap、ネストのすべてのレベルで本当にs を使用する必要がありますか?
ラッセル

@ ErnestFriedman-Hill:そうかもしれないと思っていました-「一般的な解決策」はなく、ビジネス関連の解決策しかありません。

回答:


16

クラスを作成TripleするためのフィールドがABInteger、オーバーライドhashCode()してequals()、使用Map<Triple,C>の代わりに、Map<A,Map<B,Map<Integer,C>>>

このアプローチでは、すべての要素を1つのマップに配置し、可能なキーの範囲を広げます。


反対投票者は説明しますか?ここでは、OPが実際にマップしようとしていると仮定しました:(A,B,Integer)-> C、つまりネストされたMap使用法。編集は私の考え方もサポートしています。
2012年

2
正解、これは私がマッピングしようとしているものです:(A、B、整数)からCへ

また、トリプルクラスにビジネスドメインで意味のある名前を付けます。それは何かを意味しなければなりません:-)
Martijn Verburg

の規約によりequals、これは、キーが同値関係を形成する場合にのみ機能します。私は最近、このような状況に遭遇しませんでした。キーの3番目のコンポーネントは、インスタンスを受け入れるデフォルト値か、すべての具象値が互いに異なるいくつかの具象値である可能性があります。したがって、具体的な値はデフォルトの値と等しいと見なす必要があり、推移性によって、それらはすべて等しくなくてはなりませんでした。
G.バッハ

6

[私はC#の出身ですが、答えは当てはまります]

[それほど問題ではありませんが、最後の項目はConcurrentHashMap <C、Integer>であると思います]

タイプAの関数fがあります->(B->(C-> int)) それが本当に必要なものである場合、私はすぐに答えることができません。しかし、おそらく、タイプ(A x B x C)-> intの関数fがあれば十分です。

2つのケースの違いは、最初のケースはより遅延があり、より機能的で、おそらくよりエレガントであり、「部分的に適用された」関数を使用できるということです。たとえば(タイプAの)a要素があり、afに適用しタイプ(B->(C-> int))の関数gを渡して、メソッドに送信します。ただし、関数を適切に初期化するのは少し面倒でもう少しコードが必要です。

2番目の方法は熱心でエレガントではありませんが、コーディングと理解が容易な場合があります。必要なことは、ジェネリッククラスTriple <A、B、C>を作成し、Equals()およびGetHashCode()をオーバーライドして、値のセマンティクスを持つようにすることです(2つのインスタンスが同じ要素を持っている場合は等しいと見なされます)。そして、ConcurrentHashMapTripleからIntegerであることを宣言します。最も明白なコストは、Tripleのインスタンスを作成してルックアップを実行するために、ABC要素を一度に準備する必要があることです。

編集:最後の項目が本当にConcurrentHashMap <C、Integer>である場合、ジェネリッククラスにはAB、およびIntegerフィールドがあり、マッピングはTriple <A、B、Integer>からCになります。


明確TripleMyClassするためにではなく、それを呼び出すかもしれません。あなたが本当に怠惰であるならば、ウェブの周りにもnタプルの実装があります。

実際、最後のマップはConcurrentHashMap <Integer、C>であり、ConcurrentHashMap <C、Integer>ではありませんが、それはほんの少しの詳細です。
ovdsrn 2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.