Java 是否始终调用Map.computeIfAbsent()映射函数?

Java 是否始终调用Map.computeIfAbsent()映射函数?,java,dictionary,lambda,Java,Dictionary,Lambda,在我阅读API文档时,仅当映射中不存在(不存在)键时才调用映射函数,但在Bloch的有效Java 3ed p.225(稍加修改)中的以下代码中,这里的方法似乎依赖映射函数lambda来填充树集,以便在同一个键上多次点击: public class Anagrams { public static void main(String[] args) throws IOException { File dictionary = new File("C:\\tmp\\words.

在我阅读API文档时,仅当映射中不存在(不存在)键时才调用映射函数,但在Bloch的有效Java 3ed p.225(稍加修改)中的以下代码中,这里的方法似乎依赖映射函数lambda来填充树集,以便在同一个键上多次点击:

public class Anagrams {
    public static void main(String[] args) throws IOException {
        File dictionary = new File("C:\\tmp\\words.txt");
        int minGroupSize = Integer.parseInt("3");
        Map<String, Set<String>> groups = new HashMap<>();
        try (Scanner s = new Scanner(dictionary)) {
            while (s.hasNext()) {
                String word = s.next();
                groups.
                computeIfAbsent
                  (alphabetize(word), (unused) -> new TreeSet<>())
                  .add(word);
            }
        }
        catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        for (Set<String> group : groups.values())
            if (group.size() >= minGroupSize)
                System.out.println(group.size() + ": " + group);
    }

    private static String alphabetize(String s) {
        char[] a = s.toCharArray();
        Arrays.sort(a);
        return new String(a);
    }
}
公共类字谜{
公共静态void main(字符串[]args)引发IOException{
文件字典=新文件(“C:\\tmp\\words.txt”);
int minGroupSize=Integer.parseInt(“3”);
映射组=新的HashMap();
尝试(扫描器s=新扫描器(字典)){
而(s.hasNext()){
字符串word=s.next();
组。
计算机
(按字母顺序排列(单词),(未使用)->新树集()
.加(字);
}
}
catch(filenotfounde异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
对于(设置组:groups.values())
if(group.size()>=minGroupSize)
System.out.println(group.size()+“:”+组);
}
私有静态字符串字母顺序(字符串s){
char[]a=s.toCharArray();
数组。排序(a);
返回新字符串(a);
}
}

请问我遗漏了什么?

我不知道,这对我来说似乎很简单。那里发生的事情可以改写如下:

Map<String, Set<String>> groups = new HashMap<>();
...
Set<String> wordSet = groups.get(alphabetize(word));
if(wordSet == null) {
    wordSet = new TreeSet<>();
    groups.put(alphabetize(word), wordSet);
}
wordSet.add(word);
Map groups=newhashmap();
...
Set wordSet=groups.get(按字母顺序排列(单词));
if(wordSet==null){
wordSet=newtreeset();
组。put(按字母顺序排列(单词),单词集);
}
添加(word);

基本上,如果集合已经存在于映射中(通过
字母顺序(word)
键找到),则返回该集合。否则,它将被创建。

当键没有当前值时,
computeIfAbsent
方法将仅调用映射函数。调用映射函数时,返回的值将添加到映射中

从api文档:

如果指定的键尚未与值关联(或 映射到
null
),尝试使用给定的映射计算其值 函数并将其输入此映射,除非
null


在代码中,它要么返回一个现有集,要么创建一个新的空集(并将其添加到映射中)。然后将单词添加到从
computeIfAbsent

computeIfAbsent
返回的集合中,如果键存在,则返回映射值(
TreeSet
)。那么,如果缺少密钥,将返回什么?方法名称computeIfAbsent()的语义似乎暗示映射是针对缺少密钥的条件,而不是密钥当前条件。有效Java的p225,第3版包含完全不同的代码段(对于第48项,在使流并行时请小心)。代码是从哪个项目派生的?看括号。;)从
Map.computeIfAbsent
的api文档中:“如果指定的键尚未与值关联(或映射为null),则尝试使用给定的映射函数计算其值,并将其输入此映射,除非为null。”但这实际上并没有回答问题。为什么?我的答案中的代码是在
groups.computeIfAbsent(按字母顺序排列(word),(未使用)->new TreeSet()).add(word)。还有什么不清楚的吗?你是否打开了该方法的代码,或者只是建议重写?我问的是API方法的具体实现。不,我的意思是它就是这样工作的。(差不多了;我忘了把值加回去了)。你自己看看: