Java如何按外层索引过滤移除嵌套ArrayList中的Point元素
问题核心错误
你的代码有3个直接导致结果不符合预期的问题:
- Point类构造方法存在变量遮蔽:构造方法里重新声明了
int x = x、int y = y,这两个是方法内部的局部变量,根本没有给类的成员变量x、y赋值,后续读取x/y值的时候会拿到默认值0。 - 嵌套ArrayList构造逻辑错误:循环中三次
A.add(points)添加的是同一个points列表的引用,三个子列表本质是同一个对象,修改任意一个其余两个都会同步变化,无法得到独立的子列表结果。 - 元素移除逻辑错误:你写的移除逻辑硬编码判断
x != 0,没有绑定子列表在外层的索引值,而且直接操作原始points列表,没有针对每个独立子列表做对应规则的过滤。
完整修正方案
1. 修正Point类定义
解决构造方法变量遮蔽的问题,补全基础方法:
public class Point { int x, y; public Point(int x, int y) { // 用this关键字指向类成员变量,避免和入参重名导致的赋值失败 this.x = x; this.y = y; } public int getX() { return x; } public int getY() { return y; } @Override public String toString() { return "(" + x + "," + y + ")"; } }
2. 构造独立的嵌套ArrayList
每次添加子列表时做一次列表拷贝,保证每个子列表是独立对象:
import java.util.ArrayList; public class Test { public static void main(String[] args) { ArrayList<Point> points = new ArrayList<>(); // 初始化原始点集合 points.add(new Point(0,10)); points.add(new Point(20,3)); points.add(new Point(2,5)); points.add(new Point(2,8)); ArrayList<ArrayList<Point>> A = new ArrayList<>(); for (int i = 0; i < 3; i++) { // 基于原始points拷贝生成新的独立子列表,不直接复用原引用 A.add(new ArrayList<>(points)); }
3. 按规则过滤子列表元素
用removeIf方法做元素移除,不需要手动处理遍历索引偏移的问题,逻辑更简洁安全:
// 遍历外层列表,i为当前子列表的索引 for (int i = 0; i < A.size(); i++) { ArrayList<Point> subList = A.get(i); final int targetX = i; // 移除所有x值不等于当前子列表索引的Point元素 subList.removeIf(point -> point.getX() != targetX); } // 打印结果 System.out.println(A); } }
运行结果
执行上述代码后,控制台输出完全符合预期:
[[(0,10)], [], [(2,5), (2,8)]]
如果你坚持用普通for循环做移除,注意要倒序遍历避免索引漏判,示例逻辑如下:
for (int i = 0; i < A.size(); i++) { ArrayList<Point> subList = A.get(i); int targetX = i; // 倒序遍历子列表,移除元素时不会影响未遍历元素的索引 for (int j = subList.size() - 1; j >= 0; j--) { if (subList.get(j).getX() != targetX) { subList.remove(j); } } }
内容的提问来源于stack exchange,提问作者user260541
相关产品推荐
相关产品推荐

