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

How do I remove duplicates from tree set with Custom Objects

我有一个 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());
}

结束:

这也是基于网络的呼叫。如果有人看到了加快速度的方法,那么我很想听听想法。

问题中的代码无法运行,因为compare方法违反了规则,例如

The implementor must also ensure that the relation is transitive: ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.

例如:
compare(A1, B2) 会 return <0 因为 A != B && 1 < 2
compare(B2, A3) 会 return <0 因为 B != A && 2 < 3
compare(A1, A3) 会 return 0 因为 A == A,但规则要求它 return <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();