C1,C2,C3
。 C1
优先级最高。 C2
的优先级次于 C1
,而 C3
的优先级则次于 C2
。如何在地图中创建关键字,以便如果有人要求有关
C1
的信息,我应该能够提供所有具有 C1
的值。 如果请求 C1 & C2
,则我还应该能够返回所有的值。C1,C2,C3
。 C1
优先级最高。 C2
的优先级次于 C1
,而 C3
的优先级则次于 C2
。C1
的信息,我应该能够提供所有具有 C1
的值。 如果请求 C1 & C2
,则我还应该能够返回所有的值。One Map<C1, V> and one Map<C2, V> and one Map<C3, V>.
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));
map.subMap(new Key(k1, k2, Key.c3_min), new Key(k1, k2, Key.c3_max));
MIN = new byte [0]
。对于MAX
,如果您有最大数组大小,请使用它并使用Byte.MAX_VALUE
初始化所有元素。否则,您必须选择一些实例(定义为static final
),并在compareTo
中使用==
显式检查它。最后,根据您的应用程序,null
也可能作为最大值工作,通过在compareTo
中明确考虑它。 - jopclass 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) { ... }
}
这是一个基本的框架,但应该能让你朝着正确的方向前进。
这似乎更像是一个数据库问题。如果您有一个类似下面结构的表的数据库:
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;
}
}
接下来,创建一个列表并使用功能编程库中的过滤方法。或者等待Java 8 lambdas。使用一个Map<Integer,Map<Integer,Map<Integer,Integer>>>>
太令人困惑了。
您可以使用TreeMap来实现您的用例。我假设以下内容:
您的三列映射到3个递增的整数值,即
C1 = 1,C2 = 2,C3 = 3
其中C1 = 1是最高优先级,C2 = 2是次高优先级,依此类推。
注意:您的键不一定总是整数,如果您为您的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;
}
通过“优先级”,我想你指的是通常所说的主键、次键和第三键。
如果它们都是字符串字段,将它们连接成一个单独的字符串,并将其用作键。在您的情况下,键是C1+C2+C3(其中“+”表示字符串连接)。
一个 Map 对于一个键总是只返回一个值。你不能根据键类的内容返回多个值。
简单的方法是为每种键类型保留一个单独的 Map,并根据传递的键返回相应的结果。
从我们如果可以访问数据库时如何处理这个问题上得到灵感。
假设我们有一个包含列 C1、C2、C3 和 Value 的表。
并且给出以下查询模式的要求:
在这种情况下,最好使用一个按(C1、C2、C3)特定顺序排序的多列索引 - 它将在内部创建3个单独的索引,如下所示:
我们可以在Java中遵循类似的策略 - 定义3个映射:
因此,根据传递的键来获取查询,我们选择适当的映射。
请注意,这将要求我们在所有三个映射中插入/删除以注册新数据并删除现有数据。
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);
MapVar.ObjectA.get(C1).ObjectB.get(C2);
MapVar.ObjectA.get(C1).ObjectB.get(C2).ObjectC.get(C3);;
然后您可以简单地遍历该映射并获取值。