如何将Map<K, Optional<T>>转换为Map<K, T>并过滤空值?
将Map<K, Optional>过滤空值转换为Map<K, T>的最简实现
你需要把值为Optional<T>的Map<K, Optional<T>>过滤掉空值条目,转换为Map<K, T>,同时避免Optional.get()带来的IDE警告,这里提供两种优雅的实现方式:
方式一:Java 9+ 简洁版
利用Java 9新增的Optional.stream()方法,直接将非空的Optional转换为单元素流,配合flatMap完成空值过滤:
Map<K, Optional<T>> input; Map<K, T> result = input.entrySet() .stream() .flatMap(entry -> entry.getValue().stream() .map(value -> Map.entry(entry.getKey(), value)) ) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue ));
方式二:Java 8 兼容版
如果还在使用Java 8,可以通过Optional.map将条目转换为包含键值对的Optional,再转为流实现过滤:
Map<K, Optional<T>> input; Map<K, T> result = input.entrySet() .stream() .flatMap(entry -> entry.getValue() .map(value -> new AbstractMap.SimpleEntry<>(entry.getKey(), value)) .map(Stream::of) .orElseGet(Stream::empty) ) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue ));
关于Optional.get()的警告问题
如果你最初的实现是先过滤isPresent()再调用get():
// 会触发IDE警告的写法 Map<K, T> result = input.entrySet() .stream() .filter(entry -> entry.getValue().isPresent()) .collect(Collectors.toMap( Map.Entry::getKey, entry -> entry.getValue().get() ));
IDE警告的原因是静态检查无法识别过滤逻辑已经确保Optional非空,但实际上这个写法的运行逻辑是安全的。如果不想修改代码,可以在方法或代码块上添加@SuppressWarnings("OptionalGetWithoutIsPresent")注解消除警告,但更推荐前面两种不需要调用get()的写法。
内容的提问来源于stack exchange,提问作者talex
相关产品推荐
相关产品推荐

