Реализация карты с дубликатами ключей - PullRequest
105 голосов
/ 30 июня 2009

Я хочу иметь карту с дубликатами ключей.

Я знаю, что существует много реализаций карт (Eclipse показывает мне около 50), поэтому я уверен, что должна быть такая, которая позволяет это. Я знаю, что легко написать свою собственную карту, которая делает это, но я бы предпочел использовать какое-то существующее решение.

Может быть, что-то в commons-collection или google-collection?

Ответы [ 17 ]

0 голосов
/ 24 октября 2018

что насчет такого MultiMap Impl?

public class MultiMap<K, V> extends HashMap<K, Set<V>> {
  private static final long serialVersionUID = 1L;
  private Map<K, Set<V>> innerMap = new HashMap<>();

  public Set<V> put(K key, V value) {
    Set<V> valuesOld = this.innerMap.get(key);
    HashSet<V> valuesNewTotal = new HashSet<>();
    if (valuesOld != null) {
      valuesNewTotal.addAll(valuesOld);
    }
    valuesNewTotal.add(value);
    this.innerMap.put(key, valuesNewTotal);
    return valuesOld;
  }

  public void putAll(K key, Set<V> values) {
    for (V value : values) {
      put(key, value);
    }
  }

  @Override
  public Set<V> put(K key, Set<V> value) {
    Set<V> valuesOld = this.innerMap.get(key);
    putAll(key, value);
    return valuesOld;
  }

  @Override
  public void putAll(Map<? extends K, ? extends Set<V>> mapOfValues) {
    for (Map.Entry<? extends K, ? extends Set<V>> valueEntry : mapOfValues.entrySet()) {
      K key = valueEntry.getKey();
      Set<V> value = valueEntry.getValue();
      putAll(key, value);
    }
  }

  @Override
  public Set<V> putIfAbsent(K key, Set<V> value) {
    Set<V> valueOld = this.innerMap.get(key);
    if (valueOld == null) {
      putAll(key, value);
    }
    return valueOld;
  }

  @Override
  public Set<V> get(Object key) {
    return this.innerMap.get(key);
  }

  @Override
  etc. etc. override all public methods size(), clear() .....

}
0 голосов
/ 29 августа 2018
 1, Map<String, List<String>> map = new HashMap<>();

это подробное решение имеет множество недостатков и подвержено ошибкам. Это подразумевает, что нам нужно создать экземпляр Collection для каждого значения, проверьте его присутствие перед добавлением или удалением значения, удалите его вручную, если нет значения оставлены, и так далее.

2, org.apache.commons.collections4.MultiMap interface
3, com.google.common.collect.Multimap interface 

Java-карта-дублирующие клавиши

0 голосов
/ 30 июня 2009

, чтобы быть полным, Apache Commons Collections также имеет MultiMap . Недостатком является то, что Apache Commons не использует Generics.

0 голосов
/ 02 февраля 2016

Я использовал это:

java.util.List<java.util.Map.Entry<String,Integer>> pairList= new java.util.ArrayList<>();

0 голосов
/ 13 мая 2015

С небольшим взломом вы можете использовать HashSet с дубликатами ключей. ВНИМАНИЕ: это сильно зависит от реализации HashSet.

class MultiKeyPair {
    Object key;
    Object value;

    public MultiKeyPair(Object key, Object value) {
        this.key = key;
        this.value = value;
    }

    @Override
    public int hashCode() {
        return key.hashCode();
    }
}

class MultiKeyList extends MultiKeyPair {
    ArrayList<MultiKeyPair> list = new ArrayList<MultiKeyPair>();

    public MultiKeyList(Object key) {
        super(key, null);
    }

    @Override
    public boolean equals(Object obj) {
        list.add((MultiKeyPair) obj);
        return false;
    }
}

public static void main(String[] args) {
    HashSet<MultiKeyPair> set = new HashSet<MultiKeyPair>();
    set.add(new MultiKeyPair("A","a1"));
    set.add(new MultiKeyPair("A","a2"));
    set.add(new MultiKeyPair("B","b1"));
    set.add(new MultiKeyPair("A","a3"));

    MultiKeyList o = new MultiKeyList("A");
    set.contains(o);

    for (MultiKeyPair pair : o.list) {
        System.out.println(pair.value);
    }
}
0 голосов
/ 30 июня 2009

Если имеются повторяющиеся ключи, то ключ может соответствовать более чем одному значению. Очевидное решение - сопоставить ключ со списком этих значений.

Например, в Python:

map = dict()
map["driver"] = list()
map["driver"].append("john")
map["driver"].append("mike")
print map["driver"]          # It shows john and mike
print map["driver"][0]       # It shows john
print map["driver"][1]       # It shows mike
0 голосов
/ 30 июня 2009

Не могли бы вы также объяснить контекст, для которого вы пытаетесь реализовать карту с дублирующимися ключами? Я уверен, что может быть лучшее решение. Карты предназначены для сохранения уникальных ключей по уважительной причине. Хотя, если ты действительно хотел это сделать; Вы всегда можете расширить класс, написав простой пользовательский класс карты, который имеет функцию уменьшения коллизий и позволит вам хранить несколько записей с одинаковыми ключами.

Примечание. Необходимо реализовать функцию уменьшения коллизий, чтобы коллизирующие ключи конвертировались в уникальный набор «всегда». Что-то простое, например, добавление ключа с помощью хэш-кода объекта или что-то еще?

...