getOrDefault方法
これは理解しやすいです。get(key)
空の場合はデフォルト値を返し、そうでない場合は直接返します。
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key))
? v
: defaultValue;
}
putIfAbsentメソッド
これは理解しやすいです。現在のキーが空の値に対応している場合は、それを入力してください。それ以外の場合は、何もしません。
default V putIfAbsent(K key, V value) {
V v = get(key);
if (v == null) {
v = put(key, value);
}
return v;
}
マージ方法
このメソッドはkey, value
、oldValue
空の場合はvalue
直接割り当てられた上院に渡されnewValue
、計算結果が空の場合は削除キーの実装でラムダ式の計算を実行します。
default V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
Objects.requireNonNull(value);
V oldValue = get(key);
V newValue = (oldValue == null) ? value :
remappingFunction.apply(oldValue, value);
if (newValue == null) {
remove(key);
} else {
put(key, newValue);
}
return newValue;
}
計算方法
コードを直接見てください
default V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue = get(key);
//通过传入的函数式接口计算出新value
V newValue = remappingFunction.apply(key, oldValue);
//如果新value为空,否则什么也不做。
if (newValue == null) {
// 旧value不为空,或者map中存在当前key就删除(这个是考虑key对应的oldValue就是null)
if (oldValue != null || containsKey(key)) {
remove(key);
return null;
} else {
//否则什么也不做
return null;
}
} else {
//如果新value不为空,就相当于普通的put方法
put(key, newValue);
return newValue;
}
}
したがって、計算方法は、キーとラムダ式を与えることです(機能インターフェイス関数は既知である必要があり、BiFunctionは2つのパラメーターを持つ関数インターフェイスです)。このラムダ式の結果がnullの場合は、マップを削除します。それ以外の場合は、マップを削除します。通常のプットを行うだけです。
したがって、マージして計算する違いはメソッド入参
にlambda表达式
あり、remove(key)
違いはいつです。
- マージでは、入力パラメータ値を手動で設定して、外部設定を容易にすることができます。ラムダ式のパラメータは次のとおりです。valとoldValを入力してください。それは
remove(key)
それがマップに存在するかどうかをチェックしませんkey
。 - 計算入力には値がありません。ラムダ式のパラメータは次のとおりです。キーとoldVal。その
remove(key)
際、キーがマップに存在するかどうかを確認し、存在しない場合は削除しません。しかし、コンピューティングのリターンは本当に醜いです。。マージと同じように、最後にreturnと書くだけです。。
たとえば、各要素の出現回数をカウントします。
public static void main(String[] args) throws IOException {
Map<Integer, Integer> map = new HashMap<>();
int[] nums = {
1, 2, 3, 1, 42, 32, 33, 131, 131, 2, 3, 3, 3, 1, 3, 42};
//如果你不知道getOrDefault就可能会这样做
for (int num : nums) {
Integer cnt = map.get(num);
if (cnt == null) map.put(num, 1);
else map.put(num, cnt + 1);
}
//如果你知道可能会这样做
for (int num : nums) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
//如果你知道merge,可以这样
for (int num : nums) {
map.merge(num, 1, (old, val) -> old + val);
}
//如果你知道compute,那还可以这样做。
//这里看着比上面还长,但是如果在计算新value的时候如果需要同时用到
//oldValue和key那么这个方法就可以省去一些判断
for (int num : nums) {
map.compute(num, (key, old) -> old == null ? 1 : old + 1);
}
}
computeIfAbsentメソッド
このメソッドは名前から簡単に理解できます。キーに対応する値がnullの場合は操作が実行され、それ以外の場合は何も実行されません。
ただし、計算方法とは異なります。新しい値を計算する場合、パラメータはキーのみであり、これは渡されたキーです。
default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);
V v;
if ((v = get(key)) == null) {
V newValue;
//通过key计算出新value,并且新value不为null时才进行put
if ((newValue = mappingFunction.apply(key)) != null) {
put(key, newValue);
return newValue;
}
}
return v;
}
computeIfPresentメソッド
上記とは逆に、渡されたキーで取得した値が空でない場合は操作を行い、空でない場合は何もしません。
計算方法と同様に、新しい値を計算するときは、渡されたキーとoldValueの2つのパラメーターがあります。
default V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue;
if ((oldValue = get(key)) != null) {
V newValue = remappingFunction.apply(key, oldValue);
//如果新value
if (newValue != null) {
put(key, newValue);
return newValue;
} else {
remove(key);
return null;
}
} else {
return null;
}
}
置換方法
キーに対応する値がoldValueと同じである場合は、それをnewValueに置き換えます。そうでない場合、何も実行されません。
default boolean replace(K key, V oldValue, V newValue) {
Object curValue = get(key);
if (!Objects.equals(curValue, oldValue) ||
(curValue == null && !containsKey(key))) {
return false;
}
put(key, newValue);
return true;
}