TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Map.merge() – One method to rule them all

62 pointsby wheresvic1about 6 years ago

7 comments

browdaabout 6 years ago
Yes, the final example code reads reasonably nicely, but alas -- unless ConcurrentHashMap.merge() has been rewritten since Java 8 time -- it is definitely not as performant as the author appears to think it is since the actions will be contained in a fairly long synchronized block. This is not to say the code is bad, but you can&#x27;t get around that.<p>Somewhat surprisingly, the code the author pooh-poohs is actually more performant (although it&#x27;s better if the test is for the presence of the key rather than the &quot;putIfPresent&#x2F;computeIfAbsent combination) because the JVM will properly optimize a membership test (in keyset) and the use of a ternary expression makes the action clear.
_old_dude_about 6 years ago
yes, Java 8 adds a bunch of methods to ArrayList and HashMap that makes the code a little more high level.<p>There is also another variation, using map.getOrDefault()<p><pre><code> words.forEach(word -&gt; { map.put(word, map.getOrDefault(word, 0) + 1); }); </code></pre> and then at some points you discover the Stream API<p><pre><code> var map = words.stream().collect(Collectors.groupingBy(w -&gt; w, Collectors.counting()));</code></pre>
评论 #19535693 未加载
评论 #19535561 未加载
kazinatorabout 6 years ago
This is a poor semantics. The function should always be called. In the non-existent-key case, it should be invoked on the default value that is supplied. Thus the example of the histogram tabulation would use 0 as the initial value.<p>The name is ill-chosen; this mutator doesn&#x27;t &quot;merge&quot; at all; it &quot;updates&quot; the map entry through a function, with a default value.<p>&quot;merge&quot; might be a somewhat good name for an operation that combines two maps, with a function that resolves key clashes; though since that is a kind of set union, that provides better terminology.
vojtisekabout 6 years ago
I like how the more mathematical concepts get their way to the mainstream languages. It&#x27;s making concepts such as monoids and semigroups more accessible to general public.
twicabout 6 years ago
The one thing that frustrates me about merge is that it returns the value inserted, rather than the value being replaced (as Map::put does).<p>There are good uses cases for what it does - but there are also good use cases for returning the previous value, and when i have one of those, i can&#x27;t use merge, and have to fall back to a get followed by a put.<p>Perhaps what i would really like is a Rust-style entry API, where i could use a key to obtain a Map.Entry, which i could then inspect and mutate how i liked. It might look like:<p><pre><code> Entry&lt;K, V&gt; getOrCreateEntry(K key, Function&lt;? super K, ? extends V&gt; mappingFunction) </code></pre> And then i could write:<p><pre><code> void sell(Potato) throws FarmException { ...} Map&lt;Field, Potato&gt; potatoesByField = new HashMap&lt;&gt;(); for (var potato: getAllPotatoes()) { var fieldAndPotato = potatoesByField.getOrCreateEntry(potato.getField(), f -&gt; potato); var oldPotato = fieldAndPotato.getValue(); if (potato.getWeight() &gt; oldPotato.getWeight()) { potatoAndField.setValue(potato); sell(oldPotato); } else { sell(potato); } } </code></pre> To collect my prize potatoes into a map, and sell the rest. Still ugly, but hey, at least it&#x27;s not Go.
评论 #19536188 未加载
johnchristopherabout 6 years ago
Nice, so basically it&#x27;s `INSERT ... ON DUPLICATE KEY UPDATE` ?
评论 #19535453 未加载
balodjaabout 6 years ago
Monads do exist in the programming for a reason.