3
List<Object> listObj = new ArrayList<Object[]>();
listObj.add(new Object[]{1,"abc",new Date(21/1/2001)});
listObj.add(new Object[]{1,"abc",new Date(21/1/2001)});
listObj.add(new Object[]{2,"acc",new Date(21/1/2001)});
Set<Object[]> unique = new HashSet<Object[]>();
unique.addAll();

I´m expecting to get:

{1,abc,21/1/2001},{2,acc,21/1/2001}

Instead I get:

{1,abc,21/1/2001},{1,abc,(21/1/2001},{2,acc,21/1/2001}

How to find unique entries in this example?

You Kuper
  • 1,113
  • 7
  • 18
  • 38

6 Answers6

6

Arrays in Java don't have the concept of equality that would allow this to work. You need to define a custom class with a number, string and date and implement equals/hashCode yourself to allow this to work.

Mike Q
  • 22,839
  • 20
  • 87
  • 129
  • The above is the correct way to do this. However, you could also use a `Map` and use the `Object[].toString()` as the key. I believe this will work because the `toString` for arrays includes all the elements of the array (up to a point). This is a "smelly" solution and again, the "correct" one is the one stated above. – John B Jan 30 '12 at 13:30
1

You can use a TreeSet initialized with a custom Comparator that does the check you need; there is no way for this work with arrays and the default comparator.

Viruzzo
  • 3,025
  • 13
  • 13
0

The easiest approach is to use a Set. I would strongly recommend creating a class to capture your int, string and date object

public class Foo {
    private int num;
    private String letters;
    private Date date;
}

Then you can override methods equals and hashCode to get expected behaviour from your set

Johan Sjöberg
  • 47,929
  • 21
  • 130
  • 148
0

I would encapsulate all data in the object array to a POJO.
In the POJO you can define your own equals method. e.g

public class Bean {
    private int i;
    private String l;
    private Date d;
    public int getI() {
        return i;
    }
    public void setI(int i) {
        this.i = i;
    }
    public String getL() {
        return l;
    }
    public void setL(String l) {
        this.l = l;
    }
    public Date getD() {
        return d;
    }
    public void setD(Date d) {
        this.d = d;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((d == null) ? 0 : d.hashCode());
        result = prime * result + i;
        result = prime * result + ((l == null) ? 0 : l.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof Bean))
            return false;
        Bean other = (Bean) obj;
        if (d == null) {
            if (other.d != null)
                return false;
        } else if (!d.equals(other.d))
            return false;
        if (i != other.i)
            return false;
        if (l == null) {
            if (other.l != null)
                return false;
        } else if (!l.equals(other.l))
            return false;
        return true;
    }
}
0

Arrays in Java do not override hashCode() and equals() thus comparing two arrays with the same contents (with the same length and equal elements) unexpectedly yields false.

If you use List<Object>, it should work fine. You can take advantage of Arrays.asList() utility.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
0

You could implement a thin wrapper around Object[] that would provide appropriate hashCode() and equals(). The two methods can very easily be implemented in terms of Arrays.deepHashCode() and Arrays.deepEquals():

public class Cmp {

    public static class ObjArray {
        private final Object[] arr;
        public ObjArray(Object[] arr) {
            this.arr = arr;
        }
        @Override
        public int hashCode() {
            return Arrays.deepHashCode(arr);
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            ObjArray other = (ObjArray)obj;
            return Arrays.deepEquals(arr, other.arr);
        }
    }

    public static void main(String args[]) {
        List<ObjArray> listObj = new ArrayList<ObjArray>();
        listObj.add(new ObjArray(new Object[]{1,"abc",new Date(21/1/2001)}));
        listObj.add(new ObjArray(new Object[]{1,"abc",new Date(21/1/2001)}));
        listObj.add(new ObjArray(new Object[]{2,"acc",new Date(21/1/2001)}));
        Set<ObjArray> unique = new HashSet<ObjArray>();
        unique.addAll(listObj);
        System.out.println(unique);
    }


}
NPE
  • 486,780
  • 108
  • 951
  • 1,012