fogmike
fogmike

Reputation: 13

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

I have a HashSet in my code that uses a custom type, Line, where Line has four integer fields (x1, y1, x2, y2; all representing coordinates of start and end points of the line). I populate the HashSet with a large number of these Lines. I then want to later remove specific Lines. I tried calling HashSet.remove(new Line(correct properties)), but that failed. Any ideas on how I could go about doing this?

Attached is the code for reference. The class is attempting to implement an Aldous-Broder maze generator, such that initially all walls are populated into the set, and then walls are removed (as the method carves the maze paths), before being passed to the drawing mechanics.

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);
  }

}

Upvotes: 1

Views: 77

Answers (2)

jonk
jonk

Reputation: 1494

You're HashSet is hashing the objects as they are added, a new Line(...) call will produce a new object and thus a different hashcode; hence it not working. To remove these you'll have to either keep the original objects and remove using those, or as others have said override equals and hashCode methods in your Line class so that they are based on properties of the object.

Upvotes: 0

awsome
awsome

Reputation: 2153

In class Line, override equals and hascode methods.

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

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

And here you can find the explanation of "why to implement these two methods" Why do I need to override the equals and hashCode methods in Java?

Upvotes: 6

Related Questions