如何利用Streams减少多层for循环,实现Map的过滤与转换
问题场景
现有一个已填充数据的Map<String, String>,需要对其过滤后转换为Map<Integer, String>。目前已通过嵌套循环实现该功能,希望改用Stream结合Filter来实现更简洁高效的方案。
原实现代码:
Map<String, String> infos = new Map<>(); for (String i : infos.keySet()){ Set<Integer> sets = new Set<>(); sets.add(Integer.parseInt(i)); } for (Integer i:sets){ Map<Integer, String> matches = new Map<>(); matches.put(i, infos.get(i.toString())); }
注:原代码存在语法问题,
Map和Set是接口不能直接通过new实例化,实际开发中需使用HashMap、HashSet等具体实现类,此处保留原始代码原样。
Stream优化实现方案
可以通过Stream API的filter、map和collect方法一步完成转换,同时处理非数字key导致的格式异常:
// 假设infos是已填充好的Map<String, String> Map<Integer, String> matches = infos.entrySet() .stream() // 过滤能成功转换为Integer的key .filter(entry -> { try { Integer.parseInt(entry.getKey()); return true; } catch (NumberFormatException e) { return false; } }) // 将Entry的String类型key转换为Integer,保留原value .map(entry -> new AbstractMap.SimpleEntry<>( Integer.parseInt(entry.getKey()), entry.getValue() )) // 收集为目标Map,指定重复key的处理策略(保留第一个值) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (existing, replacement) -> existing ));
代码说明
entrySet().stream():直接遍历原Map的键值对,避免单独遍历key再查询value的额外开销filter:通过捕获NumberFormatException,安全过滤掉无法转换为Integer的keymap:将原Entry的String类型key转换为Integer,生成新的键值对Entrycollect(Collectors.toMap(...)):将Stream中的Entry收集为目标Map,同时处理可能的重复key场景
如果确定原Map的key转换为Integer后不会重复,可简化toMap部分:
.collect(Collectors.toMap( entry -> Integer.parseInt(entry.getKey()), Map.Entry::getValue ));
大数据量优化:并行Stream
若原Map数据量较大,可使用并行Stream提升处理效率:
Map<Integer, String> matches = infos.entrySet() .parallelStream() // 后续过滤、映射、收集逻辑与上述一致 ...
内容的提问来源于stack exchange,提问作者Chenman
相关产品推荐
相关产品推荐

