SoFunction
Updated on 2025-04-09

Interpretation of computeIfAbsent usage of Map

ComputeIfAbsent

In Java programming,MapThe 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

computeIfAbsentMethods are introduced in Java 8 to simplify the operation of getting values ​​in Map.

If the specified key does not exist in the Map,computeIfAbsentThe 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

  • ifkeyIf it already exists in the map, the corresponding value will be returned.
  • ifkeyIf it does not exist in the map, usemappingFunctionGenerate a new value, save the map, and return this new value.

Example

Code before optimization

Not usedcomputeIfAbsentBefore 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

usecomputeIfAbsentAfter 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, usemappingFunctionGenerate 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 usecomputeIfAbsentMethods 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,computeIfAbsentThe 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 usecomputeIfAbsentMethod 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,computeIfAbsentMethods 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 usecomputeIfAbsentMethods 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,computeIfAbsentMethods ensure that each task has a corresponding dependency list. If the task does not exist, a new one is initializedArrayListand 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 usecomputeIfAbsentMethod to implement simple cache:

import .*;

public class FibonacciCache {
    private static Map&lt;Integer, Integer&gt; cache = new HashMap&lt;&gt;();
    
    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 &lt;= 1) {
            return n;
        }
        
        return (n, k -&gt; fibonacci(k - 1) + fibonacci(k - 2));
    }
}

In this example,computeIfAbsentThe 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

usecomputeIfAbsentThe method has the following advantages:

  1. Simplicity: Reduce boilerplate code, making the code more concise and easy to read.
  2. Avoid duplicate code: By usingcomputeIfAbsentMethod, we avoid explicit null checking and insertion logic.
  3. Thread safety: For some concurrent Map implementations (e.g.ConcurrentHashMap),computeIfAbsentProvides a thread-safe way to handle mapping relationships.
  4. Performance improvement: In scenarios where calculation results need to be cached or repeated calculations are avoided,computeIfAbsentCan significantly improve performance.
  5. Code consistency: By usingcomputeIfAbsent, the code is more consistent and standardized, and easy to maintain.

By understanding and usingcomputeIfAbsentMethods, 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.