如何实现可跳过Null值的Flux.collectMap替代逻辑?
解决Flux collectMap时过滤值为null的条目问题
使用reactor.core.publisher.Flux#collectMap方法时,若值生成函数(比如示例里的recognizeRedirection)返回null,最终得到的Mono<Map<String, String>>会包含值为null的条目。以下是两种实用的方法,帮你过滤掉这些null值条目,只保留有效键值对:
方案一:流处理阶段提前过滤无效值
在收集成Map之前,先把每个元素转换成键值对元组,过滤掉值为null的条目后再收集。这种方式能在流阶段就剔除无效数据,减少后续Map的处理压力:
public Mono<Map<String, String>> askForHeaders(String urlBase, String token, List<String> paths) { try { ClientImpl clientBase = ClientImpl.getClient(urlBase, token, wiretapEnabled); return clientBase.getHeadersByEndPathsExt(paths) // 将每个HttpHeadersExt转换为键(pathExt)值(重定向地址)的元组 .map(headersExt -> Tuples.of(headersExt.getPathExt(), recognizeRedirection(headersExt))) // 过滤掉值为null的元组 .filter(tuple -> tuple.getT2() != null) // 收集成最终的Map .collectMap(Tuple2::getT1, Tuple2::getT2); } catch (Exception e) { log.error("Url check error {}! <<", e.getMessage(), e.getCause()); return Mono.empty(); } }
方案二:收集后清理Map中的null值
如果需要先保留所有处理结果,再统一清理null值,可以在collectMap完成后,对生成的Map进行过滤操作:
public Mono<Map<String, String>> askForHeaders(String urlBase, String token, List<String> paths) { try { ClientImpl clientBase = ClientImpl.getClient(urlBase, token, wiretapEnabled); return clientBase.getHeadersByEndPathsExt(paths) .collectMap(HttpHeadersExt::getPathExt, this::recognizeRedirection) // 移除Map中所有值为null的条目 .map(map -> { map.values().removeIf(Objects::isNull); return map; }); } catch (Exception e) { log.error("Url check error {}! <<", e.getMessage(), e.getCause()); return Mono.empty(); } }
额外优化建议
你还可以调整recognizeRedirection方法的返回值,从String改为Optional<String>,这样能更明确地表达“可能无结果”的语义,配合流处理也更直观:
private Optional<String> recognizeRedirection(HttpHeadersExt aHeaders) { return aHeaders.toSingleValueMap().entrySet().stream() .filter(Objects::nonNull) .filter(e -> e.getKey().equals("Location")) .findFirst().map(Map.Entry::getValue); }
对应方案一的代码可以改成:
.map(headersExt -> Tuples.of(headersExt.getPathExt(), recognizeRedirection(headersExt))) .filter(tuple -> tuple.getT2().isPresent()) .collectMap(Tuple2::getT1, tuple -> tuple.getT2().get())
内容的提问来源于stack exchange,提问作者Ainz Sama
相关产品推荐
相关产品推荐

