关于 Java 集,如何通过属性删除元素?

With regards to Java Sets, how can you remove an element by its properties?

我的代码中有一个使用自定义类型 Line 的 HashSet,其中 Line 有四个整数字段(x1、y1、x2、y2;全部代表线的起点和终点的坐标)。我用大量这些行填充 HashSet。然后我想稍后删除特定的行。我尝试调用 HashSet.remove(new Line(correct properties)),但失败了。关于我如何去做这件事有什么想法吗?

附上代码供参考。 class 试图实现一个 Aldous-Broder 迷宫生成器,这样一开始所有的墙都被填充到集合中,然后在传递给绘图机制之前移除墙(因为该方法雕刻了迷宫路径) .

package tests;

import java.util.HashSet;
import java.util.Random;

public class AldousBroderTest {

static HashSet<Line> walls = new HashSet<Line>();
static Random rn = new Random();

public static void generateWalls(int x1, int y1, int x2, int y2){
    for (int i = x1; i < x2; i += 10){
        for (int j = y1; j < y2; j += 10){
            walls.add(new Line(i, j, i + 10, j));
            walls.add(new Line(i,j,i,j+10));
        }
    }
    walls.add(new Line(x1, y1, x1, y2));
    walls.add(new Line(x1, y1, x2, y1));
    walls.add(new Line(x2, y1, x2, y2));
    walls.add(new Line(x1, y2, x2, y2));
}

public static void generateMaze(int x1, int y1, int x2, int y2){
    boolean[][] visited = new boolean[x2-x1][y2-y1];
    int counter = 1;
    int currentx = rn.nextInt((x2-x1)/10)*10;
    int currenty = rn.nextInt((y2-y1)/10)*10;
    visited[currentx][currenty] = true;
    int cellcount = (x2-x1)/10 * (y2-y1)/10;
    System.out.println(cellcount);
    while (counter < cellcount){
        int direction = rn.nextInt(4); 
        switch (direction){
        case 0: 
            if(currenty == y1){break;}
            currenty -= 10;
            if(visited[currentx][currenty] == false){
                visited[currentx][currenty] = true;
                counter++;
                walls.remove(new Line(currentx, currenty+10, currentx+10, currenty+10));
            }
            break;
        case 1:
            if(currentx+10 == x2){break;}
            currentx += 10;
            if(visited[currentx][currenty] == false){
                visited[currentx][currenty] = true;
                counter++;
                walls.remove(new Line(currentx, currenty, currentx, currenty+10));
            }
            break;
        case 2:
            if(currenty+10 == y2){break;}
            currenty += 10;
            if(visited[currentx][currenty] == false){
                visited[currentx][currenty] = true;
                counter++;
                walls.remove(new Line(currentx, currenty, currentx+10, currenty));
            }
            break;
        case 3:
            if(currentx == x1){break;}
            currentx -= 10;
            if(visited[currentx][currenty] == false){
                visited[currentx][currenty] = true;
                counter++;
                walls.remove(new Line(currentx+10, currenty, currentx+10, currenty+10));
            }
            break;
        }
    }
}

public static void main(String[] args){
    generateWalls(0,0,50,50);
    generateMaze(0,0,50,50);
    Frame frame = new Frame(walls);
  }

}

在class行,覆盖equals和hashcode方法。

@Override
public boolean equals(Object obj) {
    // equals code
}

@Override
public int hashCode() {
    // hascode method
}

在这里你可以找到"why to implement these two methods"Why do I need to override the equals and hashCode methods in Java?

的解释

HashSet 正在对添加的对象进行哈希处理,new Line(...) 调用将生成一个新对象,从而生成一个不同的哈希码;因此它不起作用。要删除这些,您必须保留原始对象并使用它们删除,或者正如其他人所说,在您的 Line class 中覆盖 equalshashCode 方法,以便它们基于对象的属性。