我有一个Map<String, Integer>,它有一些键和值。我希望将所有键与作为键长度的值相关联。我已经能够用纯java和java-8来解决这个问题,但不知怎么的,我不认为在我的代码中添加一个像.collect(Collectors.toList());这样的终端操作是不需要的。
我的代码:()工作得很好
Map<String, Integer> nameLength = new HashMap<>();
nameLength.put("John", null);
nameLength.put("Antony", 6);
nameLength.put("Yassir", 6);
nameLength.put("Karein", 6);
nameLength.put("Smith", null);
nameLength.put("JackeyLent",null);
for(Entry<String, Integer> length: nameLength.entrySet()){
if(length.getValue() == null){
nameLength.put(length.getKey(),length.getKey().length());
}
}Java-8也很好,但是终端操作是无用的,我如何避免它而不使用.foreach()。
nameLength.entrySet().stream().map(s->{
if(s.getValue() == null){
nameLength.put(s.getKey(),s.getKey().length());
}
return nameLength;
}).collect(Collectors.toList());
System.out.println(nameLength);还有其他方法可以在Java-8和更高版本中实现上述逻辑吗??
发布于 2020-04-23 13:48:03
如果您要使用流,那么您应该避免副作用。Functional完全是关于纯操作的,其中输出只依赖于输入,而函数没有副作用。换句话说,创建一个新的映射,而不是修改现有的映射。
如果你这样做的话,你最好扔掉部分填充的地图,从头开始重新计算所有的东西。调用String.length()很便宜,因此不值得花很大的精力去找出哪些值是空的,哪些值不是。重新计算了所有的长度.
Map<String, Integer> newMap = nameLength.keySet().stream()
.collect(Collectors.toMap(
name -> name,
name -> name.length()
));另一方面,如果你只想修补你当前的地图流,不要真的给你买任何东西。我只是在不涉及流的情况下对其进行修改。
for (Map.Entry<String, Integer> entry: nameLength.entrySet()) {
if (entry.getValue() == null) {
entry.setValue(entry.getKey().length());
}
}或者,如前所述,您可以通过替换所有的长度来简化事情:
nameLength.replaceAll((name, __) -> name.length());(__表示未使用的变量,因此表示没有有意义的名字。)
发布于 2020-04-23 13:33:39
您几乎可以使用过滤器来标识带有空值的条目,然后使用Collectors.toMap将它们收集到以键长度作为值的Map中。
Map<String, Integer> nameLengths = nameLength.entrySet()
.stream()
.filter(entry->entry.getValue()==null)
.collect(Collectors.toMap(Map.Entry::getKey, entry->entry.getKey().length()));或者用更简单的方式在Collectors.toMap中签入
Map<String, Integer> nameLengths = nameLength.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, entry->entry.getValue() == null ? entry.getKey().length() : entry.getValue()));https://stackoverflow.com/questions/61388462
复制相似问题