TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

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

62 点作者 wheresvic1大约 6 年前

7 条评论

browda大约 6 年前
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_大约 6 年前
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 未加载
kazinator大约 6 年前
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.
vojtisek大约 6 年前
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.
twic大约 6 年前
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 未加载
johnchristopher大约 6 年前
Nice, so basically it&#x27;s `INSERT ... ON DUPLICATE KEY UPDATE` ?
评论 #19535453 未加载
balodja大约 6 年前
Monads do exist in the programming for a reason.