Java Map computeIfPresent 示例 | 如果计算键值存在则更新值

  • 例1
  • 例2
  • 例3
  • 例4
  • 参考文献

computeIfPresentjava.util.Map的默认方法,已在Java 8中引入。

computeIfPresent方法为给定的键及其相关的值计算一个指定的映射函数,然后如果指定的键的值是存在的并且不是空的,则更新该键的值。

Java文档中找到该方法的声明。

default V computeIfPresent(K key, 
            BiFunction<? super K,? super V,? extends V> remappingFunction)

key是与值关联的指定键。

remappingFunction是指定的Java BiFunction类型的映射函数,用于计算一个新的值。

computeIfPresent方法返回与指定键相关联的新值,如果没有则为空。

computeIfPresent方法的工作原理如下。

1. 如果指定的键与一个非空值相关联,并且由指定的映射函数计算的新值也不是空值,在这种情况下,computeIfPresent方法将为指定的键设置新值。

2. 如果指定的键与一个非空值相关联,并且由指定的映射函数计算的新值为空,在这种情况下,computeIfPresent方法将删除指定键的条目。

3. 如果指定的键与一个空值相关联,并且由指定的映射函数计算的新值不是空值,在这种情况下,computeIfPresent方法将不做任何事情。

4. 如果指定的键与一个非空值相关联,并且映射函数抛出了异常,在这种情况下,Map中不会有任何变化。

例1

指定的键与非空值关联

指定映射函数计算的新值也不为空。

在这种情况下,computeIfPresent方法将为指定的键放入新值。

ComputeIfPresent1.java

import java.util.HashMap;
import java.util.Map;

public class ComputeIfPresent1 {
  public static void main(String[] args) {
     Map<Integer, String> cityMap = new HashMap<>();
     cityMap.put(101, "Varanasi");
     cityMap.put(102, "Prayag");
     
     String newValue = cityMap.computeIfPresent(102, (k, v) -> v != null ? v.concat("raj") : null);
     
     System.out.println(newValue);
     System.out.println(cityMap);
  }
}

输出

Prayagraj
{101=Varanasi, 102=Prayagraj}

不使用computeIfPresent方法也可以实现同样的效果,如下所示。

ComputeIfPresent11.java

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiFunction;

public class ComputeIfPresent11 {
  public static void main(String[] args) {
     Map<Integer, String> cityMap = new HashMap<>();
     cityMap.put(101, "Varanasi");
     cityMap.put(102, "Prayag");
    
     BiFunction<Integer, String, String> remappingFunction = (k, v) -> v != null ? v.concat("raj") : null;
     int key = 102;
     String oldValue = cityMap.get(key);
     String newValue = remappingFunction.apply(key, oldValue);  
     
     if (cityMap.get(key) != null) {
       if (newValue != null)
    	 cityMap.put(key, newValue);
       else
    	 cityMap.remove(key);
     }
     
     System.out.println(newValue);
     System.out.println(cityMap);
  }
}

输出

Prayagraj
{101=Varanasi, 102=Prayagraj}

例2

指定的键与一个非空值相关联

并且由指定的映射函数计算出的新值为空。

在这种情况下,computeIfPresent方法将删除指定键的条目。

ComputeIfPresent2.java

import java.util.HashMap;
import java.util.Map;

public class ComputeIfPresent2 {
  public static void main(String[] args) {
     Map<Integer, String> cityMap = new HashMap<>();
     cityMap.put(101, "Varanasi");
     cityMap.put(102, "Prayag");
     
     cityMap.computeIfPresent(102, (k, v) -> null);
     
     System.out.println(cityMap);
  }
}

输出

{101=Varanasi}

例3

指定的键与一个空值有关

并且由指定的映射函数计算的新值不是空值。

在这种情况下,computeIfPresent方法将不做任何事情。在Map中不会有任何变化。

ComputeIfPresent3.java

import java.util.HashMap;
import java.util.Map;

public class ComputeIfPresent3 {
  public static void main(String[] args) {
     Map<Integer, String> cityMap = new HashMap<>();
     cityMap.put(101, "Varanasi");
     cityMap.put(102, null);
     
     cityMap.computeIfPresent(102, (k, v) -> "Noida");
     
     System.out.println(cityMap);
  }
}

输出

{101=Varanasi, 102=null}

例4

指定的键与非空值关联

映射函数抛出异常。

在这种情况下,Map不会有任何变化。

ComputeIfPresent4.java

import java.util.HashMap;
import java.util.Map;

public class ComputeIfPresent4 {
  public static void main(String[] args) {
	Map<Integer, String> cityMap = new HashMap<>();
	cityMap.put(101, "Varanasi");
	cityMap.put(102, "Noida");

	String newVal = null;
	try {
	  cityMap.computeIfPresent(102, (k, v) -> newVal.concat("Prayag")); //throws exception
	} catch (Throwable e) {
	  System.out.println(e);
	}

	System.out.println(cityMap);
  }
}

输出

java.lang.NullPointerException
{101=Varanasi, 102=Noida}

参考文献

【1】Java doc: Map【2】Java Map computeIfPresent() Example