Объединение двух или более (хеш) карт - PullRequest
12 голосов
/ 15 января 2011

У меня есть две Карты, которые содержат объекты одного типа:

Map<String, TaskJSO> a = new HashMap<String, TaskJSO>();
Map<String, TaskJSO> b = new HashMap<String, TaskJSO>();

public class TaskJSO { String id; }

Ключи карты являются свойствами "id".

a.put(taskJSO.getId(), taskJSO);

Я хочу получить список с: всеми значениями в «карте b» + всеми значениями в «карте a», которых нет в «карте b».

Каков самый быстрый способ выполнения этой операции?

Спасибо

РЕДАКТИРОВАТЬ: Сравнение осуществляется по id. Таким образом, два TaskJSO считаются равными, если они имеют одинаковый идентификатор (метод equals переопределяется).

Мое намерение состоит в том, чтобы узнать, какой самый быстрый способ выполнить эту операцию с точки зрения производительности. Например, есть ли разница, если я сделаю «сравнение» на карте (как предложил Питер):

Map<String, TaskJSO> ab = new HashMap<String, TaskJSO>(a);
ab.putAll(b);
ab.values()

или если вместо этого я использую набор (как предложил Нишант):

Set s = new Hashset();
s.addAll(a.values());
s.addAll(b.values());

Ответы [ 3 ]

13 голосов
/ 15 января 2011

Метод 1:

 Set s = new HashSet();
 s.addAll(a.values());
 s.addAll(b.values());

Набор - это коллекция уникальных объектов.См .: http://download.oracle.com/javase/1.4.2/docs/api/java/util/HashSet.html


Метод 2:

Этот будет сравнивать ключи, а если найдены те же ключи - значениебудет перезаписано значением более поздней карты.

Map<String, TaskJSO> ab = new HashMap<String, TaskJSO>(a);
ab.putAll(b);
ab.values()

Теперь, независимо от того, что случилось ... сравнение будет выполняться с использованием equals.Таким образом, Method-1 вызовет equals для всех значений, а Method2 вызовет его для всех ключей.В зависимости от сложности сравнения производительность будет варьироваться.

В методе 1 вам необходимо создать новый набор, но он гарантирует, что различные значения с одинаковыми ключами не будут переопределены.Но Метод 2 умный, если у вас есть уникальные идентификаторы.

Редактировать # 1 обновляется по мере обновления вопроса

9 голосов
/ 16 января 2011

Если вы хотите, чтобы все ключи / значения из b плюс все значения в a, а не в b.

Map<String, TaskJSO> ab = new HashMap<String, TaskJSO>(a);
ab.putAll(b);

Начинается с копии a и заменяет или добавляет все ключи / значения из b.

2 голосов
/ 15 января 2011

Я думаю, что вы можете сделать это за линейное время следующим образом. Пусть n и m - количество элементов в a и b соответственно.

  1. Создайте новый HashSet, содержащий все значения из b. Время O (м).

  2. Добавить все значения из b в новый список. Время O (м).

  3. Для каждого значения в a проверьте, содержит ли HashSet значений в b этот элемент. Если так, ничего не делай. В противном случае добавьте его в список. Время O (n).

В итоге используется не более O (n + m) времени, которое является линейным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...