Reputation: 144
I have an ArrayList (cntct) of ParseMessage's. ParseMessage has the
private long dateSent;
private String contact;
private String body;
with the getters and setters generated by eclipse. I am trying to get the most recent message from each contact. So I decided to do it as such
SortedSet<ParseMessage> cntctList = new TreeSet<ParseMessage>(new Comparator<ParseMessage>() {
@Override
public int compare(ParseMessage o1, ParseMessage o2)
{
if(o1 == null || o2 == null)
return 0;
if(o1.getContact().equals(o2.getContact()))
return 0;
if(o1.getDateSent() <= o2.getDateSent())
return 1;
return -1;
}
});
cntctList.addAll(cntct);
I seemed to have missed something in this though, as I am still getting a limited number of duplicates. I am using maybe 100 messages with 5 contacts and the set ends up with a size of 7
EDIT:
ParseMessage does override .equals and .hasCode As such
@Override
public int hashCode() {
return getContact().hashCode();
}
@Override
public boolean equals(Object e) {
if(!(e instanceof ParseMessage))
{
return false;
}
return ((ParseMessage) e).getContact().equals(getContact());
}
END:
Also this is for a web based call. If anyone see's a way to make this faster then I would love to hear ideas.
Upvotes: 1
Views: 263
Reputation: 159086
The code in the question doesn't work because the compare
method violates the rules, e.g.
The implementor must also ensure that the relation is transitive:
((compare(x, y)>0) && (compare(y, z)>0))
impliescompare(x, z)>0
.
For example:
compare(A1, B2)
would return <0 because A != B && 1 < 2
compare(B2, A3)
would return <0 because B != A && 2 < 3
compare(A1, A3)
would return 0 because A == A
, but the rules require it to return <0
When the rules are broken, the result is non-deterministic.
To build a collection of ParseMessage
with only the most recent message from each contact, you should create a Map
.
List<ParseMessage> cntct = /*...*/;
// Build map of contact to most recent message
Map<String, ParseMessage> cntctMap = cntct.stream().collect(Collectors.toMap(
ParseMessage::getContact,
Function.identity(),
(a, b) -> a.getDateSent() >= b.getDateSent() ? a : b
));
If a collection of messages is needed, call values():
Collection<ParseMessage> cntctList = cntctMap.values();
Upvotes: 3