Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Java8流转换带有空值的映射_Java_Java Stream - Fatal编程技术网

使用Java8流转换带有空值的映射

使用Java8流转换带有空值的映射,java,java-stream,Java,Java Stream,我正在处理一个映射,它在键和/或值中有null条目: Map<String, String> headers = new HashMap<>(); headers.put("SomE", "GreETing"); headers.put("HELLO", null); headers.put(null, "WOrLd"); headers.keySet().stream().forEach(k -> System.out.println(k + " => "

我正在处理一个
映射
,它在键和/或值中有
null
条目:

Map<String, String> headers = new HashMap<>();
headers.put("SomE", "GreETing");
headers.put("HELLO", null);
headers.put(null, "WOrLd");

headers.keySet().stream().forEach(k -> System.out.println(k + " => " + copy.get(k)));
我需要转换映射,以便将所有非空值转换为小写,如下所示:

some => greeting
hello => null
null => world
我试图使用Java 8 streams API,但下面的代码抛出了
NullPointerException

Map<String,String> copy
    = headers.entrySet()
             .stream()
             .collect(
                 Collectors.toMap(
                     it -> it.getKey() != null ? it.getKey().toLowerCase() : null,
                     it -> it.getValue() != null ? it.getValue().toLowerCase() : null));

copy.keySet().stream().forEach(k -> System.out.println(k + " => " + copy.get(k)));
地图副本
=headers.entrySet()
.stream()
.收集(
汤姆(
it->it.getKey()!=null?it.getKey().toLowerCase():null,
it->it.getValue()!=null?it.getValue().toLowerCase():null);
copy.keySet().stream().forEach(k->System.out.println(k+“=>”+copy.get(k));
如果我注释掉最后两个映射条目,程序就会执行,因此当键或值为null时,
collector.toMap
的工作方式肯定存在问题。如何使用streams API解决此问题?

问题是
toMap()
调用正在生成的基础映射实现的
merge()
函数,该函数不允许值为空

来自javadoc for(我的重点)

如果指定的键尚未与值关联或与null关联,则将其与给定的非null值关联。否则,用给定的重新映射函数的结果替换关联的值,或者在结果为null时删除

因此,使用
Collectors.toMap()
将不起作用

您可以在没有流的情况下很好地执行此操作:

Map<String,String> copy = new HashMap<>();

for(Entry<String, String> entry : headers.entrySet()){
    copy.put(entry.getKey() !=null ? entry.getKey().toLowerCase() : null, 
             entry.getValue() !=null ? entry.getValue().toLowerCase() : null
            );
}
Map copy=newhashmap();
for(条目:headers.entrySet()){
copy.put(entry.getKey()!=null?entry.getKey().toLowerCase():null,
entry.getValue()!=null?entry.getValue().toLowerCase():null
);
}

你不能在没有NPE的情况下使用
收集器.toMap()
,因为你的
映射中有一个
null
,正如@dkatzel已经解释过的,但我仍然想使用
流API

Map<String, String> headers = new HashMap<>();
headers.put("good", "AsDf");
headers.put("SomE", "GreETing");
headers.put("HELLO", null);
headers.put(null, "WOrLd");

new HashSet<>(headers.entrySet()).stream()
    .peek(entry -> entry.setValue(Objects.isNull(entry.getValue()) ? null : entry.getValue().toLowerCase()))
    .filter(entry -> !Objects.isNull(entry.getKey()) && !entry.getKey().equals(entry.getKey().toLowerCase()))
    .forEach(entry -> {
        headers.put(entry.getKey().toLowerCase(), entry.getValue());
        headers.remove(entry.getKey());
    });

System.out.println(headers);
使用收集:

final Function<String, String> fn= str -> str == null ? null : str.toLowerCase();
Map<String, String> copy = headers.entrySet().stream()
   .collect(HashMap::new,
            (m, e) -> m.put(fn.apply(e.getKey()), fn.apply(e.getValue())), 
            Map::putAll);
最终函数fn=str->str==null?null:str.toLowerCase();
Map copy=headers.entrySet().stream()
.collect(HashMap::new,
(m,e)->m.put(fn.apply(e.getKey()),fn.apply(e.getValue()),
地图:putAll);
或与

Map copy=Stream.of(头)
.collect(HashMap::new,
(m,e)->m.put(N.toLowerCase(e.getKey()),N.toLowerCase(e.getValue());
4月2日更新,或:

Map<String, String> copy = EntryStream.of(headers)
   .toMap(entry -> N.toLowerCase(entry.getKey()), entry -> N.toLowerCase(entry.getValue()));
Map copy=EntryStream.of(头)
.toMap(entry->N.toLowerCase(entry.getKey()),entry->N.toLowerCase(entry.getValue());

可能使用可选选项:toMap方法抛出NPE,因为您有一个空值,谢谢@dkatzel实际上
可以为空<代码>值不能为空我对这个示例感兴趣,但我无法让代码打印任何内容。你能详细说明一下或给我一个工作代码段吗?@WebUser它不返回任何东西,它直接修改你拥有的原始
标题
映射,运行此代码后尝试检查它的条目!谢谢如果你的答案排在第一位,我会投票赞成的。我对@dkatzel的答案很满意,我现在不想取消我的最佳答案投票。我确实投了你的一票,我希望其他人也投。非常难以维持。这也是一个很好的答案。我很高兴得到3个工作代码。现在我需要更好地理解streams和Lambda,这些答案会有所帮助!
final Function<String, String> fn= str -> str == null ? null : str.toLowerCase();
Map<String, String> copy = headers.entrySet().stream()
   .collect(HashMap::new,
            (m, e) -> m.put(fn.apply(e.getKey()), fn.apply(e.getValue())), 
            Map::putAll);
Map<String, String> copy = Stream.of(headers)
   .collect(HashMap::new, 
     (m, e) -> m.put(N.toLowerCase(e.getKey()), N.toLowerCase(e.getValue())));
Map<String, String> copy = EntryStream.of(headers)
   .toMap(entry -> N.toLowerCase(entry.getKey()), entry -> N.toLowerCase(entry.getValue()));