如何判断存储Segment的LinkedList是否构成有效多边形
Java 线段序列多边形闭合校验实现方案
首先纠正你现有代码的几个问题:
- 线段数等于3和大于3的场景校验逻辑完全一致,不需要拆分分支单独处理
- 不要用
==直接比较自定义Point类型的引用:除非你明确重写了Point类的equals方法且做了运算符重载,否则==比较的是对象内存地址,不是坐标值是否相等,应该用equals()或者直接对比x、y坐标值 - 你漏了多边形的必要校验规则:除了第一条线段起点和最后一条线段终点重合,还必须满足相邻线段首尾衔接,也就是第i条线段的终点等于第i+1条线段的起点,仅首尾重合不能判定为多边形
- 代码里
(long) polygon.size()的强转是冗余操作,size()返回的int值在和数值比较时会自动做类型提升,不需要手动转long
Stream实现方案
你不需要硬套filter()方法完成所有逻辑,Stream提供的allMatch()更适合做全量规则校验,代码可读性更高。完整实现如下:
private boolean isAClosedArea(LinkedList<Segment> polygon){ // 前置校验:空集合、线段数不足3条直接返回false if (polygon == null || polygon.size() < 3) { return false; } // 校验1:所有相邻线段满足前一段终点 = 后一段起点 boolean adjacentConnected = IntStream.range(0, polygon.size() - 1) .allMatch(idx -> { Segment currentSeg = polygon.get(idx); Segment nextSeg = polygon.get(idx + 1); return currentSeg.p2().equals(nextSeg.p1()); }); // 校验2:最后一段终点 = 第一段起点,构成闭合 boolean headTailConnected = polygon.getLast().p2().equals(polygon.getFirst().p1()); return adjacentConnected && headTailConnected; }
如果你坚持要用filter()实现,可以通过过滤不符合规则的相邻线段,统计异常线段数量判断是否合法:
// filter版本的相邻校验逻辑 long invalidSegCount = IntStream.range(0, polygon.size() - 1) .filter(idx -> { Segment currentSeg = polygon.get(idx); Segment nextSeg = polygon.get(idx + 1); // 过滤出衔接不合法的线段 return !currentSeg.p2().equals(nextSeg.p1()); }) .count(); boolean adjacentConnected = invalidSegCount == 0;
额外注意事项
- 如果你的Point类没有重写
equals()方法,需要把点重合判断替换为坐标值对比,例:// 替换 currentSeg.p2().equals(nextSeg.p1()) currentSeg.p2().getX() == nextSeg.p1().getX() && currentSeg.p2().getY() == nextSeg.p1().getY() - 如果要做严格的多边形判断,还可以追加线段无自交、无重复顶点等校验,可根据业务需求扩展。
内容的提问来源于stack exchange,提问作者anthony eleuteri
相关产品推荐
相关产品推荐

