我有一个ParseMessage的ArrayList(cntct)。 ParseMessage具有
private long dateSent;
private String contact;
private String body;
带有eclipse生成的getter和setter。 我正在尝试从每个联系人获取最新消息。 所以我决定这样做
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);
尽管如此,我似乎还是错过了一些东西,因为我仍然得到有限数量的重复。我正在使用100条带有5个联系人的消息,而该组最终的大小为7
编辑:
ParseMessage确实会覆盖.equals和.hasCode
@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:
这也是基于网络的呼叫。如果有人认为这是一种更快的方法,那么我很想听听想法。
答案 0 :(得分:3)
问题中的代码不起作用,因为compare
方法违反了规则,例如
实施者还必须确保该关系是可传递的:
((compare(x, y)>0) && (compare(y, z)>0))
暗含compare(x, z)>0
。
例如:
compare(A1, B2)
将返回<0,因为A != B && 1 < 2
compare(B2, A3)
将返回<0,因为B != A && 2 < 3
compare(A1, A3)
将返回0,因为A == A
,但是规则要求它返回<0
违反规则时,结果是不确定的。
要仅收集每个联系人的最新消息来构建ParseMessage
的集合,则应创建一个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
));
如果需要消息集合,请调用values():
Collection<ParseMessage> cntctList = cntctMap.values();