【问题标题】:MultiKeyMap get methodMultiKeyMap 获取方法
【发布时间】:2011-11-28 16:33:21
【问题描述】:

我想使用 Apache Collection 中的 MultiKeyMap,因为我需要一个带有两个键和一个值的 HashMap。 要放置元素,我这样做:

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

对于获取元素,我这样做:

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

但是 String s 来了 null...如果我传递两个键,就像这样:

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

String 带有值 value1...

当我只传递两个键中的一个时,如何扩展 MultiKeyMap 以获得正确的值?

【问题讨论】:

标签: java collections hashmap


【解决方案1】:

如果你只需要一个键来获取一个值,你就有一个普通的旧 HashMap。

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

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

对于获取元素,您可以这样做:

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

如果必须提供两个键,则需要 MultiKeyMap。

【讨论】:

    【解决方案2】:

    如果您使用两个键指定一个值,您将需要两个键才能将其取回。哈希函数并非旨在返回仅与两个键之一关联的所有可能值。您可能需要找到不同的数据结构来执行此操作。

    【讨论】:

      【解决方案3】:

      MultiKeyMap 是关于使用元组作为键,而不是将一个值与多个键匹配。使用法线贴图,只需使用不同的键输入两次值。

      删除值时需要更加小心。删除第一个键的值时,是否要自动删除具有相同值的其他键?如果是这样,您需要遍历所有键并手动删除具有相同值的键,这可能效率低下,或者保留某种反向映射以快速找到特定值的键。

      【讨论】:

        【解决方案4】:

        我不知道您的问题的确切解决方案。但我建议你像这样实现它:

        Map<K2, K1> m2;
        Map<K1, V>  m1;
        

        请看:How to implement a Map with multiple keys?

        【讨论】:

          【解决方案5】:

          看来您只是不需要 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("key2")) {
              System.out.println("the same value stored under 2 different keys!");
          }
          

          【讨论】:

            【解决方案6】:

            你不能,因为它不是 MultiKeyMap 的工作方式。将值与单独的键一起放置,而不是尝试一次使用每个键获取它。

            【讨论】:

              【解决方案7】:

              您可以使用 guava 中的表数据高度来代替它。

              【讨论】:

                【解决方案8】:

                我建议为多个键创建一个单独的类:

                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() {//}
                }
                
                }
                

                【讨论】:

                  【解决方案9】:

                  这是一个对我有用的简单 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"));
                      }
                  }
                  

                  【讨论】:

                    猜你喜欢
                    • 2016-05-24
                    • 1970-01-01
                    • 2013-09-06
                    • 1970-01-01
                    • 2019-02-19
                    • 1970-01-01
                    • 2018-05-23
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多