You Kuper
You Kuper

Reputation: 1113

Find unique entries in List<Object[]>

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?

Upvotes: 3

Views: 1685

Answers (6)

NPE
NPE

Reputation: 500227

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


}

Upvotes: 0

Viruzzo
Viruzzo

Reputation: 3025

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.

Upvotes: 1

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340713

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.

Upvotes: 0

user425367
user425367

Reputation:

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

Upvotes: 0

Johan Sj&#246;berg
Johan Sj&#246;berg

Reputation: 49187

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

Upvotes: 0

Mike Q
Mike Q

Reputation: 23219

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.

Upvotes: 6

Related Questions