使用 Multikey(1,2,3) 在 Map 中存储条目。现在只有 (1) 。我可以检索 Multikeys 中具有 (1) 的所有条目吗?

Used Multikey(1,2,3) to store entries in Map. Now only have (1) . Can I retrieve all the entries that have (1) in the Multikeys?

我使用带有 3 个参数的多键将值插入到 Map 中。现在我想检索所有在其 Multikey 中具有特定键的条目 - 我不知道其他 2 的值 ..

map.put(new MultiKey(valueA,valueB,valueC), value);

现在只有 valueA ,我需要检索 value

如果需要澄清,请询问,我会详细说明而不是投票结束。谢谢:)

..

我实际上为此创建了一个 class。

public class MultiMap<K, V> {

    private final HashMap<KeySet<K>, V> model = new HashMap<>();

    public MultiMap() {}

    public V add(V value, K first, K... keys) {
        return model.put(new KeySet<>(first, keys));
    }

    public V add(V value, Set<K> keys){
        return model.get(new KeySet<>(keys));
    }

    public Set<V> getIncludingSubsets(K... keys){
        HashSet<V> all = new HashSet<>();
        for (Entry<KeySet<K>, V> entry : model.entrySet()) {
            if (entry.getKey().containsPartially(keys)) {
                all.add(entry.getValue());
            }
        }
        return all;
    }    

    public Set<V> getIncludingSubsets(Set<K> keys){
        HashSet<V> all = new HashSet<>();
        for (Entry<KeySet<K>, V> entry : model.entrySet()) {
            if (entry.getKey().containsPartially(keys)) {
                all.add(entry.getValue());
            }
        }
        return all;
    }

    public void clear(){
        model.clear();
    }

    private class KeySet<T> extends HashSet<T>{

        private KeySet(T first, T ... rest){
            super();
            add(first);
            for (T object : rest) {
                add(object);
            }
        }

        private KeySet(Collection<T> data){
            super(data);
        }

        @Override
        public int hashCode() {
            int hash = 5;
            for (T value : this) {
                hash = 41 * hash + Objects.hashCode(value);
            }
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final KeySet<?> other = (KeySet<?>) obj;
            return hashCode() == other.hashCode();
        }

        public boolean containsPartially(T... values){
            for (T value : values) {
                if (!contains(value)) {
                    return false;
                }
            }
            return true;
        }

        public boolean containsPartially(Set<T> values){
            for (T value : values) {
                if (!contains(value)) {
                    return false;
                }
            }
            return true;
        }
    }
}

下面是一些说明其工作原理的示例代码:

MultiMap<String, String> mm = new MultiMap<>();

// "A","B","C" -> v1
// "A","B" -> v2
// "A","C" -> v3

mm.add("v1", "A", "B", "C");
mm.add("v2", "A", "B");
mm.add("v3", "A", "C");

System.out.println(mm.getIncludingSubsets("A", "C"));
System.out.println(mm.getIncludingSubsets("B"));
System.out.println(mm.getIncludingSubsets("C"));
System.out.println(mm.getIncludingSubsets("C", "B", "A"));
System.out.println(mm.getIncludingSubsets("B", "A"));
System.out.println(mm.getIncludingSubsets("B", "C"));

这将产生:

[v1, v3]
[v1, v2]
[v1, v3]
[v1]
[v1, v2]
[v1]

我敢肯定,只要有一点创意,您就可以更改此实现,使其扩展 HashMap 而不是将其作为字段。

一样简单的东西
static <V> List<V> getValues(Map<MultiKey, V> map, Object key1) {
  List<V> values = new ArrayList<>();
  for (Map.Entry<MultiKey, V> entry : map.entrySet()) {
    MultiKey key = entry.getKey();
    if (key.getKey(0).equals(key1)) {
      values.add(entry.getValue());
    }
  }
  return values;
}

可以正常工作。将其扩展为使用多个 (key1, key2, ...) 作为练习留给 reader.