2011-01-15 24 views
10

Tengo dos los mapas que contienen el mismo tipo de objetos:Unión de dos o más (hash) mapea

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

public class TaskJSO { String id; } 

Las claves mapa son las propiedades "ID".

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

Quiero obtener una lista con: todos los valores en "b" Mapa + todos los valores en "Asignar una" que no están en "Mapa B".

¿Cuál es la forma más fácil de realizar esta operación?

Gracias

EDIT: El comparaison se realiza por id. Por lo tanto, dos TaskJSO se consideran iguales si tienen la misma identificación (el método igual se anula).

Mi intención es saber cuál es la forma más rápida de realizar esta operación desde el punto de vista del rendimiento. Por ejemplo, ¿hay alguna diferencia si lo hago el "comparaison" en un mapa (como se sugiere por Peter):

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

o si por el contrario utilizo un conjunto (como se sugiere en Nishant):

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

Probablemente depende de la implementación de Java que esté utilizando. – Thomas

+0

¿Puede un mapa "id" con una 'TaskJSO' en el Mapa' a' y una 'TaskJSO' diferente en el Mapa' b'? – dkarp

+0

@dkarp sí, un mismo ID puede asignarse a dos TaskJSO diferentes en el Mapa ay el Mapa b (almacenan diferentes versiones de una misma entidad) –

Respuesta

11

Método 1:

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

Set es una colección de objetos únicos. Consulte: http://download.oracle.com/javase/1.4.2/docs/api/java/util/HashSet.html


Método 2:

This comparará claves, y si se encuentran mismas claves - el valor será reemplazado por el valor de la tarde del mapa.

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

Ahora, no importa lo que es el caso ... la comparación se llevará a cabo utilizando equals. Por lo tanto, Method-1 llamará al equals en todos los valores y Method2 lo llamará en todas las teclas. Dependiendo de cuán compleja sea la comparación, el rendimiento variará.

En el método 1, necesita crear un nuevo conjunto, pero asegura que los diferentes valores con las mismas claves no sean de más. Pero Method-2 es inteligente, si tiene ID únicos.

Edición # 1 actualiza a medida que la cuestión se actualizan

+0

Supuse que el OP quería los elementos en una lista ordenada en el orden especificado. ¿Se puede adaptar este enfoque para hacer eso? – templatetypedef

+0

OP no menciona el orden. Pero el orden se arruinará de todos modos. Para el elemento común, ¿qué orden de conjunto se prefiere? Ejemplo - A: {1,2,3}, B: {2,4,5}, una unión B: {1,2,3,4,5} o {1,3,2,4,5}, B unión A: {2,4,5,1,3} o {4,5,1,2,3}? ¡Quiero decir que es mejor que sea comparable y ordenar al hombre! :) – Nishant

+1

HashMap es un mapa desordenado. intentar mantener un orden no tendría mucho sentido. –

2

Creo que se puede hacer esto en un tiempo lineal de la siguiente manera. Deje n y m ser el número de elementos en a y b, respectivamente.

  1. Crear un nuevo HashSet contiene todos los valores de b. El tiempo es O (m).

  2. Agregue todos los valores desde b a una nueva lista. El tiempo es O (m).

  3. Para cada valor en a, compruebe si el HashSet de los valores en b contiene ese elemento. Si es así, no haga nada. De lo contrario, agréguelo a la lista. El tiempo es O (n).

Esto termina usando no más de O (n + m) tiempo, que es lineal.

9

Si desea todas las claves/valores de b más todos los valores en a, no en b.

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

Se inicia con una copia de a y reemplaza o agrega todas las claves/valores de b.

+0

No creo que esto vaya a funcionar. El op declara que 'una misma identificación puede asignarse a dos TaskJSO's diferentes en Map a y Map b'. Esto significa que 'ab.putAll (b)' fallará si 'a' y' b' tienen entradas con el mismo 'id' – ryanprayogo

+2

@ryanprayogo, ¿a qué te refieres con error? 'a' y' b' pueden tener las mismas teclas, putAll() dejará los valores que estaban en 'b' donde hay duplicados. –

+0

Lo siento, ignora lo que dije. Realmente no entendí la pregunta antes. – ryanprayogo

Cuestiones relacionadas