2011-11-28 135 views
5

我想使用Apache Collection中的MultiKeyMap,因爲我需要一個帶有兩個鍵和一個值的HashMap。 爲了把元素我這樣做:MultiKeyMap獲取方法

private MultiKeyMap multiKey = new MultiKeyMap(); 
multiKey.put("key1.1", "key2.1", "value1"); 

而對於GET元素我這樣做:

String s = multiKey.get("key1.1"); 

但字符串s卡梅斯 ...如果我通過這兩個按鍵,這樣的:

String s = multiKey.get("key1.1", "key2.1"); 

字符串s與價值觀值1 ...

012卡梅斯

如何通過只有兩個鍵之一擴展MultiKeyMap以獲得正確的值?

+0

使用正常的散列表? http://stackoverflow.com/q/822322/106261 – NimChimpsky

+0

嗯,你是對的......) – josecampos

回答

4

如果你只需要一個鍵就可以得到一個值,你就有一個普通的舊HashMap。

private Map<String, String> map = new HashMap<>(); 

map.put("key1.1", "value1"); 
map.put("key2.1", "value1"); 

而對於GET元素,你可以這樣做:當必須提供這兩個鍵

String s = map.get("key1.1"); // s == "value1" 

MultiKeyMap是必需的。

+0

嗯,你是對的......) 下一次,我需要想出來的方塊。 .. – josecampos

5

如果你用兩個鍵指定一個值,你將需要兩個鍵來恢復它。散列函數並不旨在返回僅與兩個鍵中的一個關聯的所有可能值。您可能需要找到一個不同的數據結構來執行此操作。

1

MultiKeyMap是關於使用元組作爲鍵,而不是將一個值與多個鍵匹配。使用正常的地圖,只需將您的值兩次,用不同的鍵。

刪除值時需要謹慎一些。當您刪除第一個鍵的值時,是否要自動刪除具有相同值的其他鍵?如果是這樣,則需要循環遍歷所有鍵並手動刪除具有相同值的元素,這可能效率低下,或者保留某種反向映射以快速查找特定值的鍵。

1

看來你只是不需要MultiKeyMap。你需要定期地圖。使用它可以將相同的值與任意多個鍵相關聯。

Map<String, String> map = new HashMap<String, String>(); 
Object value = ..... 
map.put("key1", value); 
map.put("key2", value); 

.................. 

if(map.get("key1") == map.get("ke2")) { 
    System.out.println("the same value stored under 2 different keys!"); 
} 
0

你不能這樣做,因爲它不是MultiKeyMap的工作方式。使用不同的密鑰輸入值,並嘗試每次使用每個密鑰。

0

取而代之的是您可以使用表數據身形從番石榴。

0

我建議創建多個密鑰一個單獨的類:

public class Test { 

Map<Shape, Book> test1 = new HashMap<>(); 
Book book = new Book("A"); 
test1.put(Shape, book); 


private class Shape { 
    String id1; 
    String id2; 
public Shape(String id1, String id2) { 
    this.id1 = id1; 
    this.id2 = id2; 
} 
@Override 
public boolean equals(Object o) {//} 
@Override 
public int hashCode() {//} 
} 

} 
0

這裏是爲我工作的簡單MultiKeyMap實現。

import java.util.Collection; 
import java.util.HashMap; 
import java.util.HashSet; 
import java.util.Map; 
import java.util.Set; 
import java.util.UUID; 

public class MultiMap<K, V> implements Map<K, V> 
{ 
    private class MultiMapEntery implements java.util.Map.Entry<K, V> 
    { 
     private final K key; 
     private V value; 

     public MultiMapEntery(K key, V value) 
     { 
      this.key = key; 
      this.value = value; 
     } 
     @Override 
     public K getKey() 
     { 
      return key; 
     } 

     @Override 
     public V getValue() 
     { 
      return value; 
     } 

     @Override 
     public V setValue(V value) 
     { 
      V oldValue = this.value; 
      this.value = value; 
      return oldValue; 
     } 
    }; 

    private final Map<K, String> keyMap = new HashMap<K, String>(); 
    private final Map<String, Set<K>> inverseKeyMap = new HashMap<String, Set<K>>(); 
    private final Map<String, V> valueMap = new HashMap<String, V>(); 

    @Override 
    public void clear() 
    { 
     keyMap.clear(); 
     inverseKeyMap.clear(); 
     valueMap.clear(); 
    } 

    @Override 
    public boolean containsKey(Object key) 
    { 
     return keyMap.containsKey(key); 
    } 

    @Override 
    public boolean containsValue(Object value) 
    { 
     return valueMap.containsValue(value); 
    } 

    @Override 
    public Set<java.util.Map.Entry<K, V>> entrySet() 
    { 
     Set<java.util.Map.Entry<K, V>> entries = new HashSet<>(); 
     for(K key : keyMap.keySet()) 
     { 
      V value = valueMap.get(key); 
      entries.add(new MultiMapEntery(key, value)); 
     } 
     return entries; 
    } 

    @Override 
    public V get(Object key) 
    { 
     return valueMap.get(keyMap.get(key)); 
    } 

    @Override 
    public boolean isEmpty() 
    { 
     return valueMap.isEmpty(); 
    } 

    @Override 
    public Set<K> keySet() 
    { 
     return keyMap.keySet(); 
    } 

    @Override 
    public V put(K key, V value) 
    { 
     String id = keyMap.get(key); 
     if(id == null) 
     { 
      id = UUID.randomUUID().toString(); 
     } 
     keyMap.put(key, id); 
     Set<K> keys = inverseKeyMap.get(id); 
     if(keys == null) 
     { 
      keys = new HashSet<>(); 
     } 
     keys.add(key); 
     inverseKeyMap.put(id, keys); 
     valueMap.put(id, value); 
     return value; 
    } 

    public V put(Set<K> keys, V value) 
    { 
     String id = null; 
     for(K key : keys) 
     { 
      id = keyMap.get(key); 
      if(id != null) // one of the keys already exists 
      { 
       break; 
      } 
     } 

     if(id == null) 
     { 
      id = UUID.randomUUID().toString(); 
     } 

     for(K key : keys) 
     { 
      keyMap.put(key, id); 
     } 
     inverseKeyMap.put(id, keys); 
     valueMap.put(id, value); 
     return value; 
    } 

    @Override 
    public void putAll(Map<? extends K, ? extends V> map) 
    { 
     for(java.util.Map.Entry<? extends K, ? extends V> entry : map.entrySet()) 
     { 
      put(entry.getKey(), entry.getValue()); 
     } 
    } 

    @Override 
    public V remove(Object key) 
    { 
     String id = keyMap.get(key); 
     keyMap.remove(key); 
     Set<K> keys = inverseKeyMap.get(id); 
     keys.remove(key); 
     V value = valueMap.get(id); 
     if(keys.size() == 0) // it was the last key, now remove the value 
     { 
      valueMap.remove(id); 
     } 
     return value; 
    } 

    @Override 
    public int size() 
    { 
     return valueMap.size(); 
    } 

    @Override 
    public Collection<V> values() 
    { 
     return valueMap.values(); 
    } 

    public static void main(String[] args) 
    { 
     MultiMap<String, String> m = new MultiMap<>(); 
     m.put("a", "v1"); 
     Set<String> s = new HashSet<>(); 
     s.add("b"); 
     s.add("c"); 
     s.add("d"); 
     m.put(s, "v2"); 

     System.out.println("size:" + m.size()); 
     System.out.println("keys:" + m.keySet()); 
     System.out.println("values:" + m.values().toString()); 
     System.out.println("a:" + m.get("a")); 
     System.out.println("b:" + m.get("b")); 
     System.out.println("c:" + m.get("c")); 
     System.out.println("d:" + m.get("d")); 

     m.remove("a"); 

     System.out.println("size:" + m.size()); 
     System.out.println("keys:" + m.keySet()); 
     System.out.println("values:" + m.values().toString()); 
     System.out.println("a:" + m.get("a")); 
     System.out.println("b:" + m.get("b")); 
     System.out.println("c:" + m.get("c")); 
     System.out.println("d:" + m.get("d")); 

     s.add("a"); 
     m.put(s, "v3"); 

     System.out.println("size:" + m.size()); 
     System.out.println("keys:" + m.keySet()); 
     System.out.println("values:" + m.values().toString()); 

     System.out.println("a:" + m.get("a")); 
     System.out.println("b:" + m.get("b")); 
     System.out.println("c:" + m.get("c")); 
     System.out.println("d:" + m.get("d")); 
    } 
}