Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Map merge VS compute, essential difference?

It seems Both merge and compute Map methods are created to reduce if("~key exists here~") when put. My problem is: add to map a [key, value] pair when I know nothing: neither key existing in map nor it exist but has value nor value == null nor key == null.

words.forEach(word ->
        map.compute(word, (w, prev) -> prev != null ? prev + 1 : 1)
);
words.forEach(word ->
        map.merge(word, 1, (prev, one) -> prev + one)
);

Is the only difference 1 is moved from Bifunction to parameter? What is better to use? Does any of merge, compute suggests key/val are existing? And what is essential difference in use case of them?

like image 734
J.J. Beam Avatar asked Sep 28 '19 11:09

J.J. Beam


People also ask

What does the merge () method on map do?

The Java HashMap merge() method inserts the specified key/value mapping to the hashmap if the specified key is already not present. If the specified key is already associated with a value, the method replaces the old value with the result of the specified function.

Can we merge two maps?

The Map. putAll() method provides a quick and simple solution to merge two maps. This method copies all key-value pairs from the second map to the first map. Since a HashMap object can not store duplicate keys, the Map.


1 Answers

The documentation of Map#compute(K, BiFunction) says:

Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). For example, to either create or append a String msg to a value mapping:

map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))

(Method merge() is often simpler to use for such purposes.)

If the remapping function returns null, the mapping is removed (or remains absent if initially absent). If the remapping function itself throws an (unchecked) exception, the exception is rethrown, and the current mapping is left unchanged.

The remapping function should not modify this map during computation.

And the documentation of Map#merge(K, V, BiFunction) says:

If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value. Otherwise, replaces the associated value with the results of the given remapping function, or removes if the result is null. This method may be of use when combining multiple mapped values for a key. For example, to either create or append a String msg to a value mapping:

map.merge(key, msg, String::concat)

If the remapping function returns null, the mapping is removed. If the remapping function itself throws an (unchecked) exception, the exception is rethrown, and the current mapping is left unchanged.

The remapping function should not modify this map during computation.

The important differences are:

  • For compute(K, BiFunction<? super K, ? super V, ? extends V>):

    • The BiFunction is always invoked.
    • The BiFunction accepts the given key and the current value, if any, as arguments and returns a new value.
    • Meant for taking the key and current value (if any), performing an arbitrary computation, and returning the result. The computation may be a reduction operation (i.e. merge) but it doesn't have to be.
  • For merge(K, V, BiFunction<? super V, ? super V, ? extends V>):

    • The BiFunction is invoked only if the given key is already associated with a non-null value.
    • The BiFunction accepts the current value and the given value as arguments and returns a new value. Unlike with compute, the BiFunction is not given the key.
    • Meant for taking two values and reducing them into a single value.
like image 94
Slaw Avatar answered Oct 03 '22 02:10

Slaw