2013-03-21 22 views
5

我需要一張地圖在我的鑰匙應根據3列的按鍵,說C1, C2, C3C1具有最高優先級。 C2有一個小於C1C3C2少一個。Java的地圖有3列

如何在地圖上創建關鍵字,如果有人要求有關C1的信息,我應該能夠給出所有具有C1的值。我也應該能夠返回所有的值,如果要求C1 & C2

+4

你能告訴我們一些測試用例嗎?你的輸入和輸出是什麼? – 2013-03-21 06:04:39

+2

問題不清楚.... – AmitG 2013-03-21 06:05:31

+0

這不是一個標準問題。讓我們根據您的使用情況來解決當前場景特有的這個問題。你能告訴C1,C2和C3的數據類型是什麼?如果它們是整數,那麼它們的範圍是什麼? – Saurabh 2013-03-21 06:15:07

回答

2

您可以使用相同的策略,在數據庫中多列索引,如果您的鍵列可排序(即在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, ... 

} 

,然後你可以得到一些價值​​中所有條目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)); 
+0

謝謝,我有問題,我的類型是字節[]。如何定義MAX和MIN值 – Avinash 2013-03-22 13:45:46

+0

假設[字節比較器](http://stackoverflow.com/questions/5108091/java-comparator-for-byte-array-lexicographic),你可以使用'MIN = new byte [ 0]'。對於'MAX',如果您有最大的數組大小,只需使用它並用'Byte.MAX_VALUE'初始化所有元素。否則,你必須選擇一些實例(定義爲'static final'),並用'=='在'compareTo'中顯式檢查它。最後,根據您的應用程序,'null'可能也會作爲最大值,通過在compareTo中顯式考慮它。 – jop 2013-03-22 14:51:32

0

「優先」,我認爲你的意思是通常被稱爲主要,次要和三級密鑰。

如果他們所有的字符串字段,將它們連接成一個字符串,並用其作爲重點。在你的情況下,關鍵是C1 + C2 + C3(其中「+」是指字符串連接)。

+0

但是,你將如何取值只對應於C1或只有C1和C2? – Saurabh 2013-03-21 06:11:22

2

使用三張地圖。

One Map<C1, V> and one Map<C2, V> and one Map<C3, V>. 

你可以用三個映射成一個類,並實現你的方法。

0

一個地圖將始終是一個關鍵只返回一個值。您不能讓它根據您的關鍵類內容返回多個值。

最簡單的方法是保持每個鍵類型都有一個單獨的地圖,並返回根據傳遞的關鍵相應的結果。

0

一個三級索引,其中一個更高級別的密鑰可以用來訪問所有較低級別的鍵和對象將需要一個三級的地圖。

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) { ... } 
} 

這是一個基本的骨架,但應該讓你朝着正確的方向前進。

0

這似乎更像是一個數據庫的問題。如果你有一個表結構如下的數據庫:

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 lambda。使用Map<Integer, Map<Integer, Map<Integer, Integer>>>>太混亂了。

0

您可以使用TreeMap來實現您的用例。我假設以下幾點: 你的三列映射到3增加整數值,即

C1 = 1,C2 = 2,C3 = 3

其中C1 = 1是最高優先級和C2 = 2在下一行,依此類推。

注意:您的密鑰不必總是整數,如果您向TreeMap提供了正確的Comparator,則可以使用任何類型的密鑰。

有了這個地方,你可以這樣做:

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; 
} 
0

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>(); 
    } 
} 

因此,這可以答應你一個美麗的結構,你不需要做更多的工作,進一步爲 如果兩個C1你可以得到的

MapVar.ObjectA.get(C1); 

所有內容, C2給出你可以叫

MapVar.ObjectA.get(C1).ObjectB.get(C2); 

如果兩個C1,C2,C3,給出你可以叫

MapVar.ObjectA.get(C1).ObjectB.get(C2).ObjectC.get(C3);; 

然後,您可以簡單地遍歷地圖並獲取值。