Reputation: 1113
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
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
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
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
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
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
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