如何使用Java8流用密钥长度替换映射中的空值

如何使用Java8流用密钥长度替换映射中的空值,java,java-stream,Java,Java Stream,我有一张地图,上面有一些键和值。我希望将所有键与值关联为键的长度。 我已经能够在纯java和java-8中解决这个问题,但不知何故,我不认为在末尾附加一个终端操作,比如.collect(Collectors.toList())这在我的代码中不是必需的 我的代码:(Java)运行良好 Map<String, Integer> nameLength = new HashMap<>(); nameLength.put("John", null); nameLen

我有一张
地图
,上面有一些键和值。我希望将所有键与值关联为键的长度。 我已经能够在纯java和java-8中解决这个问题,但不知何故,我不认为在末尾附加一个终端操作,比如
.collect(Collectors.toList())这在我的代码中不是必需的

我的代码:(Java)运行良好

 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及更高版本中执行上述逻辑的任何其他方法???

您几乎可以做到这一点,只需使用来标识具有空值的条目,然后使用将它们收集到键长度作为值的
映射中即可

Map<String, Integer> nameLengths = nameLength.entrySet()
                 .stream()
                 .filter(entry->entry.getValue()==null)
                 .collect(Collectors.toMap(Map.Entry::getKey, entry->entry.getKey().length()));

如果要使用流,则应避免副作用。函数式编程是关于纯操作的,其中输出只依赖于输入,函数没有副作用。换句话说,创建一个新地图,而不是修改现有地图

如果你这样做了,你最好扔掉部分填写的地图,从头开始重新计算。调用
String.length()
成本很低,而且不值得费心去找出哪些值是空的,哪些值不是空的重新计算所有长度。

Map<String, Integer> newMap = nameLength.keySet().stream()
    .collect(Collectors.toMap(
        name -> name,
        name -> name.length()
    ));

\uuu
表示一个未使用的变量,因此。)

为什么要设置这些人为限制:不为语句设置限制,不为每个
设置限制?这听起来像XY问题-。你想达到什么目的?也请编辑你的标题以反映你的实际问题。Java-8中的重构并没有告诉我们任何事情,不管它在做什么,它都不是重构。如果您在代码中随机添加lambda,您将一无所获。在这种特殊情况下,没有理由用流和lambda的神秘构造来替换完美且有效的
foreach
循环,而这些构造几乎与原始代码所做的一样。这对于
map
来说是可怕的用途。。可变操作,不会返回任何有趣的结果在所有答案中我觉得你是最接近的:
nameLength.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,Entry->Entry.getValue()!=null?Entry.getValue():Entry.getKey().length())
.OMG,感谢上帝投了反对票,有机会解释一下原因吗?@M.Prokhorov我的答案就是这个。重新计算所有内容比零碎地进行更容易,所以第一个和最后一个代码片段就是这样做的。中间的一个只替换
null
值,因此代码最难看。
  Map<String, Integer> nameLengths = nameLength.entrySet()
                 .stream()
                 .collect(Collectors.toMap(Map.Entry::getKey, entry->entry.getValue() == null ? entry.getKey().length() : entry.getValue()));
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());