一、簡介
Map.computeIfPresent()是Java8中對Map進行更新的一個方法,其核心是接受一個key和一個BiFunction對象,如果該key存在於Map中,則根據BiFunction計算結果並進行更新,否則不進行任何操作。這個方法操作的對象是Map,返回值也是Map,使用該方法可以簡化Map的更新操作。
二、用法
Map.computeIfPresent()方法的詳細用法如下:
default V computeIfPresent(K key, BiFunction remappingFunction)
該方法接受兩個參數:key和一個實現了BiFunction接口的函數remappingFunction。如果Map中存在該key,則使用remappingFunction計算結果,並重新插入Map中,如果不存在則返回null。
下面是一個簡單的使用示例:
Map grades = new HashMap(); grades.put("語文", 95); grades.computeIfPresent("語文", (k, v) -> v + 5); System.out.println(grades.get("語文")); // 輸出100
在上面的代碼中,我們創建了一個Map對象grades,然後往裏面插入了一條鍵值對:”語文”:95。接下來調用computeIfPresent()方法,傳遞了key為”語文”,函數remappingFunction為(k, v) -> v + 5,也就是讓已有的值加上5。最後再輸出”語文”對應的值,結果為100。
三、詳解
1. 避免空指針異常
在Java8之前,更新Map時需要進行一些判斷來避免發生空指針異常。例如,我們想要更新一個班級的學生列表,給其中的某個學生加上某個分數:
Map<String, List> classes = ...; String className = "三年級1班"; Student student = ...; int score = 100; if (classes.containsKey(className)) { List students = classes.get(className); if (students != null && students.contains(student)) { Student target = students.get(students.indexOf(student)); if (target != null) { target.setScore(score); } } }
如果在這個過程中,任何一個對象返回了null,都可能導致空指針異常。為了避免這種情況,需要寫大量的判斷。但是使用Map.computeIfPresent()方法,這個過程可以大大簡化:
Map<String, List> classes = ...; String className = "三年級1班"; Student student = ...; int score = 100; classes.computeIfPresent(className, (k, v) -> { v.stream() .filter(s -> student.equals(s)) .findFirst() .ifPresent(s -> s.setScore(score)); return v; });
在上面的代碼中,我們傳入了函數(k, v) -> {…},函數的作用是更新班級的學生列表。首先從學生列表中找到需要更新的學生,然後再設置分數,最後返回這個學生列表。這個過程中,不需要任何判斷,同時利用了Java8 Stream的特性,可以更加簡潔高效。
2. 避免重複計算
還是以上面的班級列表為例,如果要更新學生的分數,可能需要先找到班級對應的列表,然後在列表中找到學生,最後進行分數的設置。但是如果每次都要計算一遍列表,這樣就會導致性能問題。
使用Map.computeIfPresent()方法可以避免這個問題。如果在函數調用時,Map中已經存在了對應的值,則可以直接使用現有的值進行處理。例如:
Map<String, List> classes = ...; String className = "三年級1班"; Student student = ...; int score = 100; classes.computeIfPresent(className, (k, v) -> { int index = v.indexOf(student); if (index >= 0) { Student s = v.get(index); s.setScore(score); } return v; });
在上面的代碼中,使用了indexOf()方法來查找學生對應的索引值,如果索引值合法,則直接使用現有的學生對象進行處理。這樣,就避免了每次都要計算整個列表的問題。
3. 代碼示例
下面是一個完整的使用Map.computeIfPresent()方法的示例:
import java.util.HashMap; import java.util.Map; public class ComputeIfPresentDemo { public static void main(String[] args) { Map grades = new HashMap(); grades.put("語文", 95); grades.put("數學", 90); grades.put("英語", 85); // 讓所有科目加上5分 grades.replaceAll((k, v) -> v + 5); System.out.println(grades); // 輸出{英語=90, 數學=95, 語文=100} // 僅讓語文科目加上5分 grades.computeIfPresent("語文", (k, v) -> v + 5); System.out.println(grades); // 輸出{英語=90, 數學=95, 語文=105} } }
在這個示例中,我們創建了一個Map對象grades,往裏面插入了若干鍵值對,然後分別使用Map.replaceAll()和Map.computeIfPresent()方法對Map進行了更新。最終輸出更新後的Map。
四、總結
Map.computeIfPresent()方法是Java8中對Map更新的一個簡化操作,可以避免空指針異常和重複計算等問題。使用該方法,可以提高代碼的可讀性和可維護性,並且充分利用了Java8的新特性,如Stream和Lambda表達式。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/297255.html