You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

按X坐标奇偶性排序Coordinate ArrayList遇并发修改异常求解决

解决ConcurrentModificationException并实现按X奇偶性分类排序

首先,咱们先揪出你遇到的ConcurrentModificationException的核心问题:你在使用增强for循环遍历Points集合的同时,调用了Points.sort(...)方法。增强for循环底层依赖集合的迭代器,而迭代器在遍历过程中不允许集合被结构性修改(比如排序会改变元素顺序,属于结构性修改),一旦检测到这种冲突,就会抛出这个异常。

除此之外,你的代码逻辑还有额外的问题:每次循环都对整个Points集合排序,然后把当前遍历的点添加到sortedCoords,这会导致同一个点被重复添加多次,排序逻辑也完全不符合你的预期。

接下来咱们一步步重构代码,实现你的需求:把X坐标为偶数的点按X升序、Y升序排列,X为奇数的点按X降序、Y降序排列,最后合并成一个有序列表。

核心改进步骤

  • 拆分奇偶分组:先把原集合拆成X为偶数和奇数的两个子集合,避免遍历原集合时修改它
  • 多条件排序:用单个自定义Comparator实现「先X后Y」的排序规则,比多次调用sort更高效清晰
  • 合并结果:把排序后的两组数据转换回Coordinate类型,合并成最终列表

重构后的完整代码

package TSP.TSP_Algo;

import TSP.Coordinate;
import TSP.TSP_Algorithm;
import java.awt.*;
import java.util.*;

public class Convex extends TSP_Algorithm {
    private ArrayList<Coordinate> coords;

    public Convex(ArrayList<Coordinate> coords) {
        this.coords = coords;
    }

    public ArrayList<Coordinate> getSortedCoordinates() {
        ArrayList<Point> points = coordToPoint(coords);
        ArrayList<Point> evenXPoints = new ArrayList<>();
        ArrayList<Point> oddXPoints = new ArrayList<>();

        // 1. 拆分奇偶X坐标的点
        for (Point p : points) {
            if (p.x % 2 == 0) {
                evenXPoints.add(p);
            } else {
                oddXPoints.add(p);
            }
        }

        // 2. 分别排序:偶数点X升序优先,X相同则Y升序;奇数点X降序优先,X相同则Y降序
        evenXPoints.sort((a, b) -> {
            int xCompare = Integer.compare(a.x, b.x);
            return xCompare != 0 ? xCompare : Integer.compare(a.y, b.y);
        });

        oddXPoints.sort((a, b) -> {
            int xCompare = Integer.compare(b.x, a.x);
            return xCompare != 0 ? xCompare : Integer.compare(b.y, a.y);
        });

        // 3. 转换回Coordinate并合并(如需先展示奇数点,调换两行顺序即可)
        ArrayList<Coordinate> sortedCoords = new ArrayList<>();
        addPointsToCoordinates(evenXPoints, sortedCoords);
        addPointsToCoordinates(oddXPoints, sortedCoords);

        return sortedCoords;
    }

    // 辅助方法:批量将Point转换为Coordinate并加入目标集合
    private void addPointsToCoordinates(List<Point> points, List<Coordinate> target) {
        for (Point p : points) {
            target.add(new Coordinate(p.x, p.y));
        }
    }

    private ArrayList<Point> coordToPoint(ArrayList<Coordinate> coords) {
        ArrayList<Point> points = new ArrayList<>();
        for (Coordinate coord : coords) {
            points.add(new Point(coord.x, coord.y));
        }
        return points;
    }
}

关键优化点说明

  1. 彻底解决异常:通过拆分集合的方式,避免了遍历原集合时修改它的操作,从根源上消除了ConcurrentModificationException
  2. 更高效的排序逻辑:用单个Comparator实现多条件排序,比两次调用sort减少了一次全集合遍历的开销
  3. 避免重复添加:原代码中每次遍历都添加当前点,会导致同一个点被加入多次,拆分分组后只处理一次,逻辑更严谨
  4. 代码复用性提升:提取addPointsToCoordinates辅助方法,减少重复代码

内容的提问来源于stack exchange,提问作者Metin Kortbeek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:26:01