Jan
Jan

Reputation: 77

Removing custom objects from arraylist and returning the clean arrayList

I don't seem to understand how I can remove duplicate objects out of a arrayList. I have the folowing method, but it doesn't work.

    private ArrayList<Road> removeDuplicates(ArrayList<Road> array, int useless) {
        ArrayList<Road> arrayFixed = new ArrayList<>();
        for (Road road : array) {
            if (!arrayFixed.contains(road)) {
                System.out.println("Im adding this road");
                System.out.println("Road X: " + road.getX());
                System.out.println("Road Y: " + road.getY());
                arrayFixed.add(road);
            }
        }

        return arrayFixed;
    }

I have an ArrayList with roads (Object) that can have duplicates and I want the method to return an ArrayList without those duplicates.

This is the road class

public class Road {
    private double x;
    private double y;
    private String imgPath;
    private String color;

Upvotes: 0

Views: 794

Answers (2)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79435

Make sure you have overridden equals and hashCode methods in the class, Road something like:

@Override
public boolean equals(Object obj) {
    Road other = (Road) obj;
    return Objects.equals(imgPath, other.imgPath) && Objects.equals(color, other.color)
            && Objects.equals(x, other.x) && Objects.equals(y, other.y);
}

@Override
public int hashCode() {
    return Objects.hash(imgPath, color, x, y);
}

Also, instead of writing so many lines in your method, you can write just one line using Stream API as follows:

private List<Road> removeDuplicates(List<Road> array) {
    return array.stream().distinct().collect(Collectors.toList());
}

Upvotes: 3

Jakob Em
Jakob Em

Reputation: 1090

The problem with your code is not the removeDuplicates method. Instead is probably the equals method in the Road class. List.contains(...) uses this equals method to compare if the list contains the given element. So to make your code work as expected you should override the equals method in the Road class to perform the needed comparison. Depending on the Road class implementation this could look like this for example:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Road road = (Road) o;
    return Objects.equals(road.x, x) &&
            Objects.equals(road.y, y) &&
            Objects.equals(imgPath, road.imgPath) &&
            Objects.equals(color, road.color);
}

@Override
public int hashCode() {
    return Objects.hash(x, y, imgPath, color);
}

As already pointed out in the comments these methods are usually generated using your IDE and only adjusted when needed. When adjusting them you have to take into consideration that there is a contract (which can be found in the docs) between equals and hashcode which has to be considered for various reasons (for example using hashsets).

Upvotes: 3

Related Questions