这个问题已经回答了。我花了一点时间来理解(“如果映射已经包含 computeIfAbsent 中指定键的值,则不需要执行昂贵的操作”)
我把我的理解放在这里。希望这对其他人有帮助:
putIfAbsent() 的行为与 put() 一样,当 map 已经包含指定键的值时。 putIfAbsent() 只检查 key 是否为空。
如果它不为空,则返回该值,然后再次映射获取该值。
但是,在computeIfAbsent() 中,对键和值都进行了空检查。在空值检查期间,如果它不为空,则地图对象中的现有值
分配给 newValue 并返回。这就是为什么不需要再次获取值,因为地图中的现有值被重复使用。
参考以下方案:
public class MapTest1 {
public static final String AJAY_DEVGAN = "Ajay Devgn";
public static final String AUTOBIOGRAPHY = "Autobiography";
public static void main(String[] args) {
MapTest1 mt = new MapTest1();
mt.testPutCompute();
}
private void testPutCompute() {
Map<String, List<String>> movies = getMovieObject();
System.out.println("\nCalling putIfAbsent method.....");
//System.out.println(movies.get(AJAY_DEVGAN));
//movies.put(AJAY_DEVGAN, getAjayDevgnMovies());
movies.putIfAbsent(AJAY_DEVGAN, getAjayDevgnMovies());
System.out.println("\nCalling computeIfAbsent method......");
//System.out.println(movies.get(AUTOBIOGRAPHY));
movies.computeIfAbsent(AUTOBIOGRAPHY, t -> getAutobiographyMovies());
}
private Map<String, List<String>> getMovieObject() {
Map<String, List<String>> movies = new HashMap<>();
movies.put(AJAY_DEVGAN, getAjayDevgnMovies());
movies.put(AUTOBIOGRAPHY, getAutobiographyMovies());
System.out.println(movies);
return movies;
}
private List<String> getAutobiographyMovies() {
System.out.println("Getting autobiography movies");
List<String> list = new ArrayList<>();
list.add("M.S. Dhoni - The Untold Story");
list.add("Sachin: A Billion Dreams");
return list;
}
private List<String> getAjayDevgnMovies() {
System.out.println("Getting Ajay Devgn Movies");
List<String> ajayDevgnMovies = new ArrayList<>();
ajayDevgnMovies.add("Jigar");
ajayDevgnMovies.add("Pyar To Hona Hi Tha");
return ajayDevgnMovies;
}
}
从接口Map.class中参考putIfAbsent()和computeIfAbsent()的以下代码
public interface Map<K,V> {
.....
default V putIfAbsent(K key, V value) {
V v = get(key);
if (v == null) {
v = put(key, value);
}
return v;
}
default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);
V v;
if ((v = get(key)) == null) {
V newValue;
if ((newValue = mappingFunction.apply(key)) != null) {
put(key, newValue);
return newValue;
}
}
return v;
}
.........
}