Intersection of java.util.Map
Asked Answered
H

6

48

Is there a method in java.util.Map or any util to perform an intersection on two maps? (To intersect two maps by the "keys")

I am not able to find any. I can always implement my own intersection logic, but I was hoping there is already some operation in one of the java.util.* classes that would do this.

Hobnailed answered 1/11, 2012 at 15:39 Comment(3)
Do you want to see if the keys of one map are also keys in the other map? Do the values also matter, or just the keys?Naker
@dashrb: just the keys, not the values.Hobnailed
@mandy, please update your question with this information. :-)Dachy
C
60

How about:

Map map1 = ...;
Map map2 = ...;
Map result = new ...(map1);
result.keySet().retainAll(map2.keySet());

or:

Map map1 = ...;
Map map2 = ...;
Set result = new ...(map1.keySet());
result.retainAll(map2.keySet());
Changteh answered 1/11, 2012 at 15:43 Comment(8)
I have 2 maps, map1 and map2. I want to perform an intersection between map1 and map2. I would have to create a new Set if i try to use this approach.Hobnailed
That is an optional operation, will it work for all such keySets?Fanjet
By 'that' you mean Set#retainAll(). It'll work with java.util.* collections, and the concurrent collections. I'd expect it to work with all popular implementations of mutable maps, but obviously you'd need to verify for the particular implementation. @ruakh: Good edit, thanks.Changteh
So now you have a Map with the values from map1 for intersecting keys. What about such values from map2?Humbug
See the clarification in the comments on the question: the keys are of interest, the values "do not matter".Changteh
I saw that, so why bother creating a new result Map at all? One of the implementations from Apache Commons or Guava will get the intersecting keys if that's all @Hobnailed is interested in.Humbug
Fair point, I've updated the answer to include an option for just obtaining a set. I suggested a JRE method because it seems likely to be more applicable. That is: not everyone can easily add dependencies to their application (for example, because binary size is a problem, bureaucracy, etc), nor necessarily wants to for something that they can easily do without.Changteh
I found second answer very useful. Not needing externals like Apache Commons or Guava is a real bonus (to me). I find an answer that is two lines need not be in the JRE. Perhaps this could be placed in your own Utils function and hardened against nulls and Exceptions, and the Set could/should be typed. I see no reason to include any of that in the answer as this answers the question concisely. Well done.Billyebilobate
B
16

If you're using Guava, you can use Maps.difference to get a MapDifference object, from which you can extract the entriesInCommon() and entriesDiffering() as maps. (Disclosure: I contribute to Guava.)

Bis answered 1/11, 2012 at 16:7 Comment(2)
The OP seems to be only be concerned about the keys. The Guava library is not clearly documented in this respect, but it seems to be comparing also the values, no? Please document appropriately.Production
Read the docs for MapDifference -- it tells you that entriesDiffering(), for example, "returns an unmodifiable map describing keys that appear in both maps, but with different values."Bis
H
4

Guava's Sets.intersection(Set, Set) should do the job, with the keySet of each Map passed in as parameters.

Humbug answered 1/11, 2012 at 15:43 Comment(3)
How would you convert that back into a Map?Anthropomorphize
Well that depends on what you want to do with the values corresponding to intersecting keys surely?Humbug
The OP appears to only care about the keys, so it's fine.Bis
E
0

To test for intersection you can use the containsAll() operation. Which 'Returns true if this set contains all of the elements of the specified collection. If the specified collection is also a set, this method returns true if it is a subset of this set.'

To get a collection of these intersecting elements you can use the retainAll() operation instead.

These methods are both found here

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Set.html

Expedition answered 1/11, 2012 at 15:43 Comment(1)
That doesn't give you the intersection, though. It just tells you whether one set of keys is a subset of the other. Finding the intersection means returning the common keys/values.Changteh
F
0

I would recommend apache collectionUtils#intersection

Do the following:

 Collection intersection=    
      CollectionUtils.intersection(map1.keySet(),map2.keySet());
Fanjet answered 1/11, 2012 at 15:46 Comment(0)
N
0

Loop over one map's keys, see if they're in the second map:

private Map getIntersection(Map mapOne, Map mapTwo)
{
    Map intersection = new HashMap();
    for (Object key: mapOne.keySet())
    {
        if (mapTwo.containsKey(key))
           intersection.put(key, mapOne.get(key));
    }
    return intersection;
}
Naker answered 1/11, 2012 at 15:49 Comment(3)
Set intersection = new HashMap(); ? Really?Heffron
hahaha oops. That should say "Map". I'll edit. (Thanks for noticing, after 7 years. I can only assume my real code has similar latent but obvious bugs!)Naker
Your code helped me, and that's why I cared to correct it :) Thanks!Heffron

© 2022 - 2024 — McMap. All rights reserved.