Сравнение хэш-карт - PullRequest
       4

Сравнение хэш-карт

1 голос
/ 12 ноября 2010

У меня есть два хеш-карты.Это просто пример 2 хеш-карт, может быть n хеш-карт.

Они выглядят так

HashMap A = [(a, 23),(b,25),(c,43),(d,34)]
HashMap B = [(a, 32),(b,52),(d,55)]

Теперь я хочу сравнить эти хеш-карты таким образом, чтобы я мог поместить недостающий ключ 'c' в HashMap B со значением 0.

Как я могу это сделать?Помните, что может быть n HashMaps.

Ответы [ 5 ]

3 голосов
/ 12 ноября 2010

Гуава может кое-что вам помочь:

Map<K, V> a = ...
Map<K, V> b = ...
MapDifference<K, V> difference = Maps.difference(a, b);

A MapDifference затем позволяет вам проверять различную разницу между двумя картами, например, какие записи у левого Map имеют то, чего нет у правого, и наоборот.

Если вы хотите убедиться, что на карте нет никаких записей a, которых нет b, вы можете сделать что-то вроде этого:

b.putAll(difference.entriesOnlyOnLeft());

То, как вы обрабатываете серию карт, зависит от того, что именно вам нужно с ними делать, что вы на самом деле не объясняли ... но вы можете просто просмотреть их, выполнив вышеописанное с каждой парой карт, чтобы убедиться, что последняя карта содержит, по крайней мере, каждую запись, которая есть на любой другой карте, например.

2 голосов
/ 12 ноября 2010

Давайте назовем «целевой» HashMap тем, который получит недостающие ключи и «источники» каждого из остальных. Для каждого ключа в каждом источнике, если цель не содержит ключ, тогда свяжите ноль с этим ключом в цели:

for (Map<String,Number> source : sources) {
  for (String key : source.keySet() ) {
    if (!target.containsKey(key)) {
      target.put(key, 0);
    }
  }
}

Теперь, если вы хотите убедиться, что на всех картах есть все ключи от всех других карт, вам следует сначала вычислить весь набор ключей и добавить недостающие на каждую карту:

Set<String> allKeys = new HashSet<String>();
for (Map<String,Number> map : allHashMaps) {
  allKeys.addAll(map.keySet());
}
for (Map<String,Number> map : allHashMaps) {
  for (String key : allKeys) {
    if (!map.containsKey(key)) {
      map.put(key, 0);
    }
  }
}

Оба решения работают при O (n * k), где n - это количество карт, а k - среднее количество ключей в каждой карте.

1 голос
/ 12 ноября 2010

Вы можете сделать A.keySet().removeAll(B.keySet()), что даст вам все предметы в A, которых нет в B

0 голосов
/ 12 ноября 2010
Set<Key> keys = new HashSet<Key>(/* if you have any perspective on size, could put it here */);
for (Map<Key, ?> map : n-maps) keys.addAll(map.keySet());
for (Map<Key, ?> map : n-maps) for (Key k : keys) if(!map.containsKey(k)) map.put(k, defaultObject);

, где n-maps - это Iterable или массив ваших карт, а defaultObject - это любое значение по умолчанию, которое вы хотите добавить туда.

Есть несколько разумных маршрутов оптимизации, напримерсравнивая размер набора keys с размером целевого объекта map, который позволил бы вам разветвляться на пару разумных категорий: одного размера, очень близкого к 0, keys.size() или другому.

0 голосов
/ 12 ноября 2010
public static <T> void mergeKeys(Map<T, Integer> target, Map<T, ?>... sources) {
    Set<T> newKeys = new HashSet<T>();
    for (Map<T, ?> source : sources)
        newKeys.addAll(source.keySet());
    newKeys.removeAll(target.keySet());
    for (T key : newKeys)
        target.put(key, 0);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...