Java ClassCastException当Treeset.add()时,尽管实现了与compareTo方法类似的

Java ClassCastException当Treeset.add()时,尽管实现了与compareTo方法类似的,java,classcastexception,comparable,compareto,Java,Classcastexception,Comparable,Compareto,我在下面显示了一个班级联系人。我希望每个联系人对象都有其他联系人的列表。我选择了一个TreeSet,因为我想避免在同一个列表中出现重复的联系人。我的Contact类实现了Comparable,并有一个构造的compareTo()方法来比较实例字符串变量。我理解在添加到树集时使用compareTo方法,因为添加的元素会立即排序 当我尝试将联系人[](请参见下面的我的setContacts()方法)中的联系人对象添加到我的树集时,我收到一个ClassCastException。我的system.ou

我在下面显示了一个班级联系人。我希望每个联系人对象都有其他联系人的列表。我选择了一个
TreeSet
,因为我想避免在同一个列表中出现重复的联系人。我的Contact类实现了
Comparable
,并有一个构造的compareTo()方法来比较实例字符串变量。我理解在添加到树集时使用compareTo方法,因为添加的元素会立即排序

当我尝试将联系人[](请参见下面的我的setContacts()方法)中的联系人对象添加到我的树集时,我收到一个
ClassCastException
。我的system.out消息是:

Exception in thread "main" java.lang.ClassCastException: shared.Contact cannot be cast to java.lang.String
at java.text.Collator.compare(Unknown Source)
at java.util.TreeMap.compare(Unknown Source)
at java.util.TreeMap.put(Unknown Source)
at java.util.TreeSet.add(Unknown Source)
at shared.Contact.setContacts(Contact.java:51) <-- right here is the TreeSet.add()
at server.Server.readInContacts(Server.java:191)
at server.Server.main(Server.java:51)
线程“main”java.lang.ClassCastException中的异常:共享。无法将联系人强制转换为java.lang.String 位于java.text.Collator.compare(未知源) 位于java.util.TreeMap.compare(未知源) 位于java.util.TreeMap.put(未知源) 位于java.util.TreeSet.add(未知源) 在shared.Contact.setContacts(Contact.java:51)c.getName()返回一个字符串,然后用这个调用equals。。所以一个字符串被传递给equals

第一行等号尝试将字符串转换为触点。。。繁荣

compare方法将对它尝试比较的对象调用equals。

c.getName()返回一个字符串,然后使用此字符串调用equals。。所以一个字符串被传递给equals

第一行等号尝试将字符串转换为触点。。。繁荣


compare方法将在它尝试比较的对象上调用equals。

答案就在Collator.java中:

public int compare(Object o1, Object o2) {
return compare((String)o1, (String)o2);
}
我现在还不清楚,但你到底为什么要穿自己的衣领? 你在处理非ascii码吗

这里还有一个不一致之处:compareTo()==0应该与equals()相同,特别是因为在这两种情况下,您似乎只关心“name”

因此,一方面,你声明你想要删除相同的条目,因此你使用了比较身份,但是你使用了一个Collator,它肯定会产生与equals不一致的结果

如果您只想删除冗余,那么跳过Collator,使用HashSet或TreeSet而不使用Collator

或者,如果必须使用经过整理的名称,则使用

TreeMap<String,Contact> contacts = new TreeMap<String,Contact>(Collator.getInstance());
contacts.put(contact.getName(),contact);
TreeMap contacts=newtreemap(Collator.getInstance());
contacts.put(contact.getName(),contact);
然后,您可以使用:

Collection<Contact> uniqueContacts = contacts.values();
Collection uniqueContacts=contacts.values();

答案就在Collator.java中:

public int compare(Object o1, Object o2) {
return compare((String)o1, (String)o2);
}
我现在还不清楚,但你到底为什么要穿自己的衣领? 你在处理非ascii码吗

这里还有一个不一致之处:compareTo()==0应该与equals()相同,特别是因为在这两种情况下,您似乎只关心“name”

因此,一方面,你声明你想要删除相同的条目,因此你使用了比较身份,但是你使用了一个Collator,它肯定会产生与equals不一致的结果

如果您只想删除冗余,那么跳过Collator,使用HashSet或TreeSet而不使用Collator

或者,如果必须使用经过整理的名称,则使用

TreeMap<String,Contact> contacts = new TreeMap<String,Contact>(Collator.getInstance());
contacts.put(contact.getName(),contact);
TreeMap contacts=newtreemap(Collator.getInstance());
contacts.put(contact.getName(),contact);
然后,您可以使用:

Collection<Contact> uniqueContacts = contacts.values();
Collection uniqueContacts=contacts.values();

Equals在排序/比较中没有被调用。查看堆栈跟踪。此外,compareTo()和equals()都使用字符串“name”。请看我的帖子below@chris当前位置你是对的,我假设被比较对象的相等值被调用。我的错!我刚刚做了一些测试,回来问了更多的问题,现在已经回答了!hahaEquals在排序/比较中没有被调用。查看堆栈跟踪。此外,compareTo()和equals()都使用字符串“name”。请看我的帖子below@chris当前位置你是对的,我假设被比较对象的相等值被调用。我的错!我刚刚做了一些测试,回来问了更多的问题,现在已经回答了!hahaI完全误解了拼贴器的用途。我没有一个Collator的需要,只是想一个没有重复的列表,可以按字符串值组织。删除
Collater.getInstance()
部分修复了整个问题。谢谢。为了清楚起见:列表和集合有很大的区别。列表是可索引的(list.get(0);),而集合不是。集合只包含唯一的元素。它们的迭代顺序依赖于实现。集合需要一些开销,因为它们需要根据当前集合检查插入的每个对象的标识,以保持无重复。列表没有这样的要求。我完全误解了Collator的用法。我没有一个Collator的需要,只是想一个没有重复的列表,可以按字符串值组织。删除
Collater.getInstance()
部分修复了整个问题。谢谢。为了清楚起见:列表和集合有很大的区别。列表是可索引的(list.get(0);),而集合不是。集合只包含唯一的元素。它们的迭代顺序依赖于实现。集合需要一些开销,因为它们需要根据当前集合检查插入的每个对象的标识,以保持无重复。清单没有这样的要求。