ComputeIfAbsent
In Java programming,Map
The interface provides a convenient methodcomputeIfAbsent
, it can be used to get the value corresponding to the key from the map. If the value does not exist, create a new value using the provided Function, then save it in the map, and finally return the newly created value
The computeIfAbsent method is a way to simplify the operation of Map introduced in Java 8. This method reduces manual checking and insertion of boilerplate code by automatically checking whether key-value pairs exist and generating missing values. It not only makes the code more concise and readable, but also improves the efficiency and consistency of operations.
Introduction to computeIfAbsent method
computeIfAbsent
Methods are introduced in Java 8 to simplify the operation of getting values in Map.
If the specified key does not exist in the Map,computeIfAbsent
The specified function is called to generate a new value and associate it with the key.
This way, developers do not need to explicitly check whether the key exists, thus reducing boilerplate code.
Method signature
default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
Parameter description
-
key
: The key to look for in the map. -
mappingFunction
: Function used to generate default values.
Return value
- if
key
If it already exists in the map, the corresponding value will be returned. - if
key
If it does not exist in the map, usemappingFunction
Generate a new value, save the map, and return this new value.
Example
Code before optimization
Not usedcomputeIfAbsent
Before the method, we usually write this:
Map<String, Set<Pet>> statistics = new HashMap<>(); Set<Pet> pets = (threadName); if (pets == null) { pets = new HashSet<>(); (threadName, pets); }
Optimized code
usecomputeIfAbsent
After the method, the code becomes more concise and easy to read:
Map<String, Set<Pet>> statistics = new HashMap<>(); Set<Pet> pets = (threadName, k -> new HashSet<>());
How it works
default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { (mappingFunction); V v; if ((v = get(key)) == null) { V newValue; if ((newValue = (key)) != null) { put(key, newValue); return newValue; } } return v; }
Detailed explanation
- Check the existing values: First check whether the specified key already exists in the map.
-
Generate new value: If the key does not exist, use
mappingFunction
Generate a new value. - Store new values: Associate the newly generated value with the key and store it in the map.
- Return value: Returns the value associated with the key (newly generated or existing).
Examples in practical applications
Example 1: Statistics the number of times a word appears
We have a text that wants to count the number of times each word appears. We can usecomputeIfAbsent
Methods to simplify statistical logic:
import .*; public class WordCounter { public static void main(String[] args) { String text = "hello world hello Java hello world"; String[] words = (" "); Map<String, Integer> wordCount = new HashMap<>(); for (String word : words) { (word, k -> 0); (word, (word) + 1); } ((k, v) -> (k + ": " + v)); } }
In this example,computeIfAbsent
The method ensures that each word is initialized to 0 when it first appears, and then we simply increase the count value.
Example 2: Grouped Student List
Suppose we have a group of students’ grade records and we want to group students by score segment. For example, those with scores above 90 are divided into one group, 80-89 are divided into one group, and so on.
We can usecomputeIfAbsent
Method to implement this function:
import .*; public class StudentGrouper { public static void main(String[] args) { List<Student> students = ( new Student("Alice", 85), new Student("Bob", 92), new Student("Charlie", 87), new Student("David", 72), new Student("Eve", 90) ); Map<String, List<String>> gradeGroups = new HashMap<>(); for (Student student : students) { String gradeCategory = getGradeCategory(()); (gradeCategory, k -> new ArrayList<>()).add(()); } ((k, v) -> (k + ": " + v)); } public static String getGradeCategory(int score) { if (score >= 90) { return "90-100"; } else if (score >= 80) { return "80-89"; } else if (score >= 70) { return "70-79"; } else { return "Below 70"; } } } class Student { private String name; private int score; public Student(String name, int score) { = name; = score; } public String getName() { return name; } public int getScore() { return score; } }
In this example,computeIfAbsent
Methods ensure that each fraction segment (e.g. "90-100") is correctly initialized as a new oneArrayList
, and then we add the student's name to the corresponding group.
Example 3: Building a dependency graph
Suppose we have a set of tasks, each of which may depend on other tasks. We want to build a dependency graph that represents the dependencies of each task. We can usecomputeIfAbsent
Methods to simplify the construction of the graph:
import .*; public class DependencyGraph { public static void main(String[] args) { Map<String, List<String>> dependencies = new HashMap<>(); addDependency(dependencies, "Task1", "Task2"); addDependency(dependencies, "Task1", "Task3"); addDependency(dependencies, "Task2", "Task4"); addDependency(dependencies, "Task3", "Task4"); addDependency(dependencies, "Task4", "Task5"); ((k, v) -> (k + " depends on " + v)); } public static void addDependency(Map<String, List<String>> dependencies, String task, String dependency) { (task, k -> new ArrayList<>()).add(dependency); } }
In this example,computeIfAbsent
Methods ensure that each task has a corresponding dependency list. If the task does not exist, a new one is initializedArrayList
and add dependencies.
Example 4: Cache calculation results
In some scenarios, calculating certain values can be very time consuming, so we want to cache the calculation results for efficiency. We can usecomputeIfAbsent
Method to implement simple cache:
import .*; public class FibonacciCache { private static Map<Integer, Integer> cache = new HashMap<>(); public static void main(String[] args) { (fibonacci(10)); // Output: 55 (fibonacci(20)); // Output: 6765 (fibonacci(30)); // Output: 832040 } public static int fibonacci(int n) { if (n <= 1) { return n; } return (n, k -> fibonacci(k - 1) + fibonacci(k - 2)); } }
In this example,computeIfAbsent
The method is used to cache the calculation results of the Fibonacci sequence. For each n, if there is no corresponding value in the cache, the calculation is performed and the result is cached. This method greatly improves the computing efficiency and avoids repeated calculations.
Advantages summary
usecomputeIfAbsent
The method has the following advantages:
- Simplicity: Reduce boilerplate code, making the code more concise and easy to read.
-
Avoid duplicate code: By using
computeIfAbsent
Method, we avoid explicit null checking and insertion logic. -
Thread safety: For some concurrent Map implementations (e.g.
ConcurrentHashMap
),computeIfAbsent
Provides a thread-safe way to handle mapping relationships. -
Performance improvement: In scenarios where calculation results need to be cached or repeated calculations are avoided,
computeIfAbsent
Can significantly improve performance. -
Code consistency: By using
computeIfAbsent
, the code is more consistent and standardized, and easy to maintain.
By understanding and usingcomputeIfAbsent
Methods, developers can write more concise, easy to read and efficient code, making them more handy when operating maps.
The above is personal experience. I hope you can give you a reference and I hope you can support me more.