如何使用自定义对象从树集中删除重复项

时间:2018-10-16 16:09:17

标签: java duplicates treeset

我有一个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:

这也是基于网络的呼叫。如果有人认为这是一种更快的方法,那么我很想听听想法。

1 个答案:

答案 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();