简体   繁体   English

两个或更多(哈希)映射的联合

[英]Union of two or more (hash)maps

I have two Maps that contain the same type of Objects: 我有两个包含相同类型对象的地图:

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

public class TaskJSO { String id; }

The map keys are the "id" properties. 地图键是“id”属性。

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

I want to obtain a list with: all values in "Map b" + all values in "Map a" that are not in "Map b". 我想获得一个列表:“Map b”中的所有值+“Map a”中不在“Map b”中的所有值。

What is the fastest way of doing this operation? 这项操作的最快方法是什么?

Thanks 谢谢

EDIT: The comparaison is done by id. 编辑:比较由id完成。 So, two TaskJSOs are considered as equal if they have the same id (equals method is overrided). 因此,如果两个TaskJSO具有相同的id(等于方法被覆盖),则认为它们是相等的。

My intention is to know which is the fastest way of doing this operation from a performance point of view. 我的目的是从性能的角度来了解哪种方法最快。 For instance, is there any difference if I do the "comparaison" in a map (as suggested by Peter): 例如,如果我在地图中执行“比较”(如彼得所建议的那样),是否有任何区别:

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

or if instead I use a set (as suggested by Nishant): 或者如果我使用一套(如Nishant所建议):

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

Method 1: 方法1:

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

Set is collection of unique objects. Set是唯一对象的集合。 Refer: http://download.oracle.com/javase/1.4.2/docs/api/java/util/HashSet.html 请参阅: http//download.oracle.com/javase/1.4.2/docs/api/java/util/HashSet.html


Method 2: 方法2:

This will compare keys, and if same keys are found -- the value will be overwritten by the later Map's value. 将比较键,如果找到相同的键 - 该值将被后面的Map的值覆盖。

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

Now, no matter what's the case... the comparison will take place using equals . 现在,无论是什么情况......比较将使用equals So, Method-1 will call equals on all the values and Method2 will call it on all the keys. 因此,Method-1将在所有值上调用equals ,Method2将在所有键上调用它。 Depending on how complex the comparison is the performance will vary. 根据比较的复杂程度,性能会有所不同。

In method 1, you need to create a new Set but it ensures that different values with same keys are not overwitten. 在方法1中,您需要创建一个新的Set,但它确保具有相同键的不同值不会被覆盖。 But Method-2 is smart, if you have unique IDs. 但是如果你有唯一的ID,方法2很聪明。

Edit#1 updates as the question was updated 问题更新后编辑#1更新

If you want all the key/values from b plus all the values in a, not in b. 如果你想要b中的所有键/值加上a中的所有值,而不是b中的所有值。

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

Starts with a copy of a and replaces or adds all the key/values from b. 从a的副本开始,替换或添加b中的所有键/值。

I think you can do this in linear time as follows. 我想你可以在线性时间内做到这一点,如下所示。 Let n and m be the number of elements in a and b , respectively. nm分别为ab的元素数。

  1. Create a new HashSet containing all the values from b . 创建一个包含b中所有值的新HashSet Time is O(m). 时间是O(m)。

  2. Add all of the values from b to a new list. b中的所有值添加到新列表中。 Time is O(m). 时间是O(m)。

  3. For each value in a , check whether the HashSet of values in b contains that element. 对于中的每个值a ,检查是否HashSet值的b含有该元素。 If so, do nothing. 如果是这样,什么也不做。 Otherwise, add it to the list. 否则,将其添加到列表中。 Time is O(n). 时间是O(n)。

This ends up using no more than O(n + m) time, which is linear. 这最终使用不超过O(n + m)的时间,这是线性的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM