キーが 3 つの列に基づくマップが必要C1, C2, C3
です。C1
優先度が最も高い。C2
は よりも 1 つ少なく、C1
とよりC3
も 1 つ少ないですC2
。
C1
誰かが に関する情報を求めた場合に、 を持つすべての値を与えることができるように、マップにキーを作成するにはどうすればよいですかC1
。また、要求された場合はすべての値を返すことができるはずですC1 & C2
キーが 3 つの列に基づくマップが必要C1, C2, C3
です。C1
優先度が最も高い。C2
は よりも 1 つ少なく、C1
とよりC3
も 1 つ少ないですC2
。
C1
誰かが に関する情報を求めた場合に、 を持つすべての値を与えることができるように、マップにキーを作成するにはどうすればよいですかC1
。また、要求された場合はすべての値を返すことができるはずですC1 & C2
3つのマップを使用します。
One Map<C1, V> and one Map<C2, V> and one Map<C3, V>.
3つのマップをクラスにラップして、メソッドを実装できます。
データベースの複数列インデックスと同じ戦略を使用できます。キー列を並べ替えることができ (つまり、Java では列を並べる必要がありますComparable
)、最初の列を除くすべての最大値と最小値を簡単に定義できます。
整数列の例:
public class Key implements Comparable<Key> {
int c1, c2, c3;
private static final int c2_min = Integer.MIN_VALUE;
private static final int c2_max = Integer.MAX_VALUE;
private static final int c3_min = Integer.MIN_VALUE;
private static final int c3_max = Integer.MAX_VALUE;
@Override
public int compareTo(Key o) {
if (c1!=o.c1) return Integer.compare(c1, o.c1);
if (c2!=o.c2) return Integer.compare(c2, o.c2);
return Integer.compare(c3, o.c3);
}
// constructor, equals, ...
}
k1
次に、次のc1
ように、ある値のすべてのエントリを取得できます。
map.subMap(new Key(k1, Key.c2_min, 0), new Key(k1, Key.c2_max, 0));
同様に、最初の 2 つの列を使用します。
map.subMap(new Key(k1, k2, Key.c3_min), new Key(k1, k2, Key.c3_max));
「優先度」とは、通常、プライマリキー、セカンダリキー、およびターシャリキーと呼ばれるものを意味すると思います。
それらがすべて文字列フィールドである場合は、それらを1つの文字列に連結し、それをキーとして使用します。あなたの場合、キーはC1 + C2 + C3です(「+」は文字列の連結を示します)。
上位レベルのキーを使用してすべての下位レベルのキーとオブジェクトにアクセスできる 3 レベルのインデックスには、3 レベルのマップが必要です。
class ThreeLevelMap<K1,K2,K3,V>
{
private Map<K1,Map<K2,Map<K3,V>>> store = new HashMap<K,Map<K2,Map<K3,V>>>();
...
public V put(K1 key1, K2 key2, K3 key3, V value) { ... }
public V get(K1 key1, K2 key2, K3 key3) { ... }
public static class TLMEntry<K1,K2,K3,V>
{
...
}
public Collection<TLMEntry<K1,K2,K3,V>> get(K1 key1, K2 key2) { ... }
public Collection<TLMEntry<K1,K2,K3,V>> get(K1 key1) { ... }
}
これは基本的なスケルトンですが、正しい方向に進む必要があります。
private class C {
public C() {
Map <Object ,String> ObjectC =new HashMap<Object, String>();
}
}
private class B {
public B() {
Map <Object ,C> ObjectB =new HashMap<Object, C>();
}
}
private class A {
public A() {
Map <Object ,B> ObjectA =new HashMap<Object, B>();
}
}
したがって、これにより、A のすべてのコンテンツを取得できるため、これ以上の作業を行う必要のない美しい構造が約束される可能性があります。
MapVar.ObjectA.get(C1);
C1、C2の両方が指定されている場合は、呼び出すことができます
MapVar.ObjectA.get(C1).ObjectB.get(C2);
C1、C2、C3 の両方が指定されている場合は、呼び出すことができます
MapVar.ObjectA.get(C1).ObjectB.get(C2).ObjectC.get(C3);;
次に、マップを単純に反復して値を取得できます。
Map は、キーに対して常に 1 つの値のみを返します。キークラスのコンテンツに基づいて複数の値を返すことはできません。
簡単な方法は、キーの種類ごとに個別のマップを保持し、渡されたキーに基づいて適切な結果を返すことです。
これはデータベースの問題のようです。次のような構造のテーブルを持つデータベースがあるとします。
CREATE TABLE MyMap (
id IDENTITY PRIMARY KEY,
c1 int, -- Change data types as needed.
c2 int,
c3 int,
v int);
次に、それに対して SELECT ステートメントを発行するだけです。インメモリ Java データベースのいずれかを使用したい場合があります。
それをしたくない場合は、コンテナ クラスの値クラスを作成することで、純粋に Java で同等の機能を実行できます。
class Cdata {
private int c1;
private int c2;
private int c3;
private int v;
// Constructors and getters elided.
public boolean match(int c1) {
return this.c1 == c1;
}
public boolean match(int c1, int c2) {
return match(c1) && this.c2 == c2;
}
public boolean match(int c1, int c2, int c3) {
return match(c1, c2) && this.c3 == c3;
}
}
次に List を作成し、関数型プログラミング ライブラリをフィルター メソッドと共に使用します。または、Java 8 ラムダを待ちます。a の使用Map<Integer, Map<Integer, Map<Integer, Integer>>>>
は混乱しすぎます。
TreeMap を使用してユースケースを実現できます。私は次のことを想定しています: あなたの 3 つの列は 3 つの増加する整数値にマップされます。
C1=1、C2=2、C3=3
ここで、C1 = 1 が最高の優先順位で、C2 = 2 が次の優先順位です。
Comparator
注: キーは必ずしも整数である必要はありませんTreeMap
。
これを配置すると、次のようなことができます。
TreeMap<Integer, String> treeMap = new TreeMap<Integer, String>();
treeMap.put(1, "One");
treeMap.put(2, "two");
treeMap.put(3, "three");
List<String> list = getMappedValues(treeMap, 1);// returns One, Two, Three
//List<String> list = getMappedValues(treeMap, 2);// returns Two, Three
//List<String> list = getMappedValues(treeMap, 3);// returns Three
//List<String> list = getMappedValues(treeMap, 4);// returns null
if(list != null){
//do something with the list of values
}
private static List<String> getMappedValues(TreeMap<Integer, String> map, Integer key) {
Entry<Integer, String> e = map.ceilingEntry(key);
if(e == null){
return null;
}
List<String> list = new ArrayList<String>();
while(e != null){
list.add(e.getValue());
key = e.getKey();
e = map.higherEntry(key);
}
return list;
}