如何从使用自定义对象的树集中删除重复项
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();
我有一个 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))
impliescompare(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();