47

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.

mandy
  • 735
  • 1
  • 9
  • 24

6 Answers6

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());
Martin Ellis
  • 9,603
  • 42
  • 53
  • 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. – mandy Nov 01 '12 at 15:45
  • That is an optional operation, will it work for all such keySets? – Woot4Moo Nov 01 '12 at 15:49
  • 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. – Martin Ellis Nov 01 '12 at 15:59
  • So now you have a `Map` with the values from `map1` for intersecting keys. What about such values from `map2`? – darrengorman Nov 01 '12 at 16:03
  • See the clarification in the comments on the question: the keys are of interest, the values "do not matter". – Martin Ellis Nov 01 '12 at 16:04
  • 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 @mandy is interested in. – darrengorman Nov 01 '12 at 16:12
  • 1
    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. – Martin Ellis Nov 01 '12 at 16:21
  • 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. – brightmatter Mar 16 '21 at 16:31
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.)

Iulian Popescu
  • 2,595
  • 4
  • 23
  • 31
Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • 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. – Roland Aug 30 '16 at 14:28
  • 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." – Louis Wasserman Aug 30 '16 at 19:09
4

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

darrengorman
  • 12,952
  • 2
  • 23
  • 24
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

calderonmluis
  • 547
  • 4
  • 11
  • 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. – Martin Ellis Nov 01 '12 at 15:50
0

I would recommend apache collectionUtils#intersection

Do the following:

 Collection intersection=    
      CollectionUtils.intersection(map1.keySet(),map2.keySet());
Woot4Moo
  • 23,987
  • 16
  • 94
  • 151
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;
}
dashrb
  • 952
  • 4
  • 10