Использовал Multikey(1,2,3) для хранения записей на карте. Теперь только есть (1) . Могу ли я получить все записи, которые имеют (1) в Multikeys?

Я вставил значения в карту, используя Multikey с 3 параметрами. Теперь я хотел бы получить все записи, которые имеют определенный ключ в их Multikey - и я не имею представления о значениях других 2 ..

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

Теперь есть только значение A, мне нужно получить значение

Если требуется разъяснение, пожалуйста, спросите, и я уточню, а не голосование, чтобы закрыть.. Спасибо:)

..

2 ответа

Решение

Что-то простое, как

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, ...) оставлено читателю в качестве упражнения.

Я на самом деле создал класс только для этого.

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 вместо того, чтобы иметь один в качестве поля.

Другие вопросы по тегам