似乎合并和计算映射方法都是为了在放置时减少 if("~键存在这里~"(。 我的问题是:当我一无所知时,将 [键,值] 对添加到映射中:映射中既不存在键也不存在,但具有值或值 == null 或键 == 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)
);
唯一的区别 1 是从双函数移动到参数吗? 什么更好用?是否有任何合并,计算表明键/值存在? 它们的用例有什么本质区别?
>Map#compute(K, BiFunction)
的文档说:
尝试计算指定键及其当前映射值的映射(如果没有当前映射,则
null
(。例如,要创建或追加String
msg
到值映射:map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))
(方法
merge()
通常更容易用于此类目的。如果重映射函数返回
null
,则映射将被删除(如果最初不存在,则保持不存在(。如果重新映射函数本身引发(未选中的(异常,则会重新引发异常,并且当前映射保持不变。重映射函数不应在计算过程中修改此映射。
Map#merge(K, V, BiFunction)
的文件说:
如果指定的键尚未与值关联或与 null 关联,则将其与给定的非 null 值相关联。否则,将关联的值替换为给定重映射函数的结果,或者如果结果
null
则删除。当组合一个键的多个映射值时,此方法可能有用。例如,要创建或追加String
msg
值映射,请执行以下操作:map.merge(key, msg, String::concat)
如果重映射函数返回
null
,则删除映射。如果重新映射函数本身引发(未选中的(异常,则会重新引发异常,并且当前映射保持不变。重映射函数不应在计算过程中修改此映射。
重要的区别是:
-
对于
compute(K, BiFunction<? super K, ? super V, ? extends V>)
:-
始终调用
BiFunction
。 BiFunction
接受给定的键和当前值(如果有(作为参数,并返回一个新值。- 用于获取键和当前值(如果有(、执行任意计算并返回结果。计算可能是缩减操作(即合并(,但并非必须如此。
-
始终调用
-
对于
merge(K, V, BiFunction<? super V, ? super V, ? extends V>)
:-
仅当给定键已与非 null 值关联时,才会调用
BiFunction
。 BiFunction
接受当前值和给定值作为参数,并返回一个新值。与compute
不同,BiFunction
没有钥匙。- 用于获取两个值并将它们简化为单个值。
-
仅当给定键已与非 null 值关联时,才会调用
如果映射函数(如您的情况(仅取决于当前映射值,则可以同时使用两者。但我更喜欢:
compute
是否可以保证给定键的值存在。在这种情况下,不需要合并方法采用的额外值参数。merge
给定键是否可能不存在任何值。在这种情况下,合并的优点是null
不必由映射函数处理。