如何用Java 8 Stream API改写List转TreeMap的代码实现
Java 8 Stream 改写找最近点代码的正确方案
原代码逻辑回顾
原代码遍历点列表,将每个点到父起始顶点的距离作为键存入TreeMap,利用TreeMap的有序性,直接取第一个条目对应的点即为距离最近的点。
你编写代码的问题
- 键生成函数写法错误:
parentStartVertex.distanceTo(point->point)写法有误,distanceTo方法需要接收Point3d对象,而非lambda表达式,正确的键生成逻辑应为point -> parentStartVertex.distanceTo(point)。 - 未处理键重复情况:普通
Collectors.toMap遇到相同距离的点时会抛出IllegalStateException,但原代码的TreeMap.put会直接覆盖旧值,两者行为不一致。 - 冗余的Map转换:先收集到普通
Map再转TreeMap完全没必要,直接收集到TreeMap更高效。
正确改写方案
方案一:保持原TreeMap逻辑的Stream写法
直接将流收集到TreeMap中,同时指定键重复时的合并规则(与原代码逻辑一致,保留新值):
private Point3d findClosestNodeToParentStartNode1(List<Point3d> points, Point3d parentStartVertex) { TreeMap<Double, Point3d> distanceMap = points.stream() .collect(Collectors.toMap( point -> parentStartVertex.distanceTo(point), point -> point, (existingPoint, newPoint) -> newPoint, // 距离相同时覆盖旧值,对齐原逻辑 TreeMap::new )); return distanceMap.firstEntry().getValue(); }
方案二:更高效的直接找最小值(推荐)
无需构建整个有序Map,直接利用Stream的min方法,通过比较点到父顶点的距离找到最近点,性能更优:
private Point3d findClosestNodeToParentStartNode1(List<Point3d> points, Point3d parentStartVertex) { // 空列表场景返回null,可根据业务需求改为抛出异常等处理方式 return points.stream() .min(Comparator.comparingDouble(point -> parentStartVertex.distanceTo(point))) .orElse(null); }
内容的提问来源于stack exchange,提问作者Ambrish Mayank
相关产品推荐
相关产品推荐

