0

So I have two identical maps with String as key and Integer as value and I know that after certain event only 1 value in map2 increment by 1.

Map<String, Integer> map1 = new HashMap<>();
map1.put("First", 1)
map1.put("Second", 2)
map1.put("Third", 3)
Map<String, Integer> map2 = new HashMap<>();
map2.put("First", 1)
map2.put("Second", 3)
map2.put("Third", 3)

So my question is how I can return "Second" key because its value is incremented by 1.

  • 1
    https://stackoverflow.com/questions/12721735/how-to-receive-difference-of-maps-in-java/24814200 does this answer your question? – Andreas Feb 18 '22 at 15:43
  • @Andreas Not really because both maps have same keys, so method given in provided question will always return empty map. – Вукашин Лекић Feb 18 '22 at 17:19
  • Please have a second look (and at least try the proposed solution). Guava `Maps.difference` returns the diff in two maps. If you call `entriesDiffering` on the returned `MapDifference` you get what you asked for. – Andreas Feb 18 '22 at 20:16
  • @Andreas yeah, but I would not import whole library just for a simple task like this, anyway i found solution by using stream and filter options. `Map razlika = map1.entrySet().stream().filter(entry -> !entry.getValue().equals(map2.get(entry.getKey()))).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));` – Вукашин Лекић Feb 18 '22 at 22:43
  • 1
    Does this answer your question? [How to receive difference of maps in java?](https://stackoverflow.com/questions/12721735/how-to-receive-difference-of-maps-in-java) – Andreas Feb 19 '22 at 07:54

3 Answers3

3

The stream pipeline in your answer works, but might be more complex than necessary. Essentially it's performing a difference operation on the sets of entries of each map. You can do this using the collections bulk operation removeAll instead of a stream, like so:

// setup
var map1 = Map.of("First", 1, "Second", 2, "Third", 3);
var map2 = Map.of("First", 1, "Second", 3, "Third", 3);

// compute difference of entry sets
var difference = new HashMap<>(map1);
difference.entrySet().removeAll(map2.entrySet());

difference ==> {Second=2}
Stuart Marks
  • 127,867
  • 37
  • 205
  • 259
0

It seems you just want to get the keys and without the values, so the following method will do exactly that.

public static <K> List mapDifference(Map<? extends K, ? extends Object> map1, Map<? extends K, ? extends Object> map2)
{
        List<K> keys = new ArrayList<K>();
        Set<Map.Entry<? extends K, ? extends Object>> set;
        Map<? extends K, ? extends Object> other;
        if(map1.size() > map2.size()) {
            set = map1.entrySet(); other = map2;
        } else {
            set = map2.entrySet(); other = map1;
        }
        Iterator<Map.Entry<? extends K, ? extends Object>> iterator = set.iterator();
        while(iterator.hasNext()) {
            Map.Entry<? extends K, ?  extends Object> entry = iterator.next();
            K key = entry.getKey();
            if(!other.containsKey(key) || !other.get(key).equals(entry.getValue())) {
                keys.add(key);
            }
        }
        return keys;
}

TESTS

Map<String, Integer> map1 = new HashMap<>();
map1.put("First", 1);
map1.put("Second", 2);
map1.put("Third", 3);
Map<String, Integer> map2 = new HashMap<>();
map2.put("First", 1);
map2.put("Second", 3);
map2.put("Third", 3);

List<String> diff = mapDifference(map1, map2);
System.out.println(diff);
[Second]
Map<String, Integer> map1 = new HashMap<>();
map1.put("First", 1);
map1.put("Second", 2);
map1.put("Third", 3);
Map<String, Integer> map2 = new HashMap<>();
map2.put("First", 1);
map2.put("Second", 3);
map2.put("Third", 3);
map2.put("Forth", 4);

List<String> diff = mapDifference(map1, map2);
System.out.println(diff);
[Second, Forth]
Darkman
  • 2,941
  • 2
  • 9
  • 14
  • `Map razlika = map1.entrySet().stream().filter(entry -> !entry.getValue().equals(map2.get(entry.getKey()))).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));` is far more simple – Вукашин Лекић Feb 18 '22 at 22:45
0
Map<String, Integer> difference = map1.entrySet().stream()
    .filter(entry -> !entry.getValue().equals(map2.get(entry.getKey())))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Lino
  • 19,604
  • 6
  • 47
  • 65
  • It helps more if you supply an explanation why this is the preferred solution and explain how it works. We want to educate, not just provide code. – the Tin Man Feb 21 '22 at 05:19