Java 是否始终调用Map.computeIfAbsent()映射函数?
在我阅读API文档时,仅当映射中不存在(不存在)键时才调用映射函数,但在Bloch的有效Java 3ed p.225(稍加修改)中的以下代码中,这里的方法似乎依赖映射函数lambda来填充树集,以便在同一个键上多次点击: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.
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方法的具体实现。不,我的意思是它就是这样工作的。(差不多了;我忘了把值加回去了)。你自己看看: