Remove duplicate in ArrayList of Custom objects

12,692

Solution 1

Given MyObject like this:

class MyObject {
    private final double x;
    private final double y;

    public MyObject(double x, double y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        MyObject myObject = (MyObject) o;

        if (Double.compare(myObject.x, x) != 0) return false;
        if (Double.compare(myObject.y, y) != 0) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result;
        long temp;
        temp = Double.doubleToLongBits(x);
        result = (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(y);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }
}

You can implement a unique method that returns a list with unique elements only:

private List<MyObject> unique(List<MyObject> list) {
    List<MyObject> uniqueList = new ArrayList<>();
    Set<MyObject> uniqueSet = new HashSet<>();
    for (MyObject obj : list) {
        if (uniqueSet.add(obj)) {
            uniqueList.add(obj);
        }
    }
    return uniqueList;
}

And a unit test for it to verify it works:

@Test
public void removeDups() {
    List<MyObject> list = Arrays.asList(new MyObject(0, 0), new MyObject(0, 0), new MyObject(0.5, 0.5), new MyObject(0.5, 0.6), new MyObject(1, 1));
    List<MyObject> results = Arrays.asList(new MyObject(0, 0), new MyObject(0.5, 0.5), new MyObject(0.5, 0.6), new MyObject(1, 1));
    assertEquals(results, unique(list));
}

Note: it's important to implement both equals and hashCode for this to work, because of the use of a hash map. But you should always do this anyway in your custom classes: provide appropriate equals and hashCode implementations. Btw, I didn't write those equals and hashCode methods. I let my IDE (IntelliJ) generate them automatically from the fields x and y of the class.

Solution 2

Make sure to override equals() method in your custom Object(MyObject).

Then add them into a Set. Now you have unique result set.

Share:
12,692
user2335528
Author by

user2335528

Updated on June 12, 2022

Comments

  • user2335528
    user2335528 almost 2 years

    i'm trying to remove duplicate objects from my array.

    I have my custom which is made of two double : x and y.

    What i want to do is to remove duplicate ( (x && y) == (x1 && y1)) and if x == x1 i want to keep the object which has the higher y.

    ArrayList<MyObject> list = [x(0),y(0)], [x(0),y(0)], [x(0.5),y(0.5], [x(0.5),y(0.6)], [x(1),y(1)]; 
    ArrayList<MyObject> results = [x(0),y(0)], [x(0.5),y(0.6)], [x(1),y(1)]; 
    

    I tried to implement the equals method but i do not how to use it :

    public boolean equals(Object obj) {
        if (obj == null || !(obj instanceof MyObject)) {
            return false;
        }
        return (this.x == ((MyObject)obj).x);
    }
    

    list is always ordered using Collections.sort by x.

    Thanks for all.

  • user2335528
    user2335528 over 9 years
    ok i get it that i need to implement equals and hashcode, but next what do i do with this ?
  • sockeqwe
    sockeqwe over 9 years
    I have updated my answer. Just to clarify: you have to override equals() and hashCode() for your MyObject class
  • Tristan
    Tristan over 8 years
    When answering questions it is best to explain in more detail so that it can be more easily understood by other users of the site.