我有一个班级联系人,我在下面显示。我希望每个Contact对象都有一个其他Contacts的列表。我选择了TreeSet
,因为我想避免在同一个列表中重复使用联系人。 My Contact类实现Comparable
并且具有构造的compareTo()方法,用于比较实例String变量。我理解在添加到TreeSet时使用了compareTo方法,因为添加的元素会立即排序。
当我尝试将Contact [](请参阅下面的setContacts()方法)中的Contact对象添加到我的TreeSet时,我收到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)
我不明白的是,在我构建的任何类中都没有,我尝试将任何东西转换为String。以下是我的整个Contact课程。
有没有人看到任何错误或者看到为什么会发生异常?
如果有人告诉我其他可能相关的内容,我会很乐意发布更多代码。我不知道还有什么重要的。提前谢谢。
package shared;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.text.Collator;
import java.util.LinkedList;
import java.util.TreeSet;
public class Contact implements Serializable, Comparable<Contact>{
private static final long serialVersionUID = 1L;
private String name;
private boolean online;
private TreeSet<Contact> contacts;
private ObjectOutputStream oos;
private ObjectInputStream ois;
public Contact(String name){
this(name, null, null);
}
public Contact (String name, ObjectInputStream ois, ObjectOutputStream oos){
this.name = name;
this.ois = ois;
this.oos = oos;
contacts = new TreeSet<Contact>(Collator.getInstance());
}
public String getName(){
return name;
}
public void logIn(ObjectInputStream ois, ObjectOutputStream oos){
this.ois = ois;
this.oos = oos;
}
public ObjectInputStream getObjectInputStream(){
return ois;
}
public ObjectOutputStream getObjectOutputStream(){
return oos;
}
public void setOnlineStatus(boolean status){
online = status;
}
public boolean isOnline(){
return online;
}
public void setContacts(Contact[] contacts){
this.contacts.clear();
for (Contact c: contacts){
this.contacts.add(c); <-- right here is where my exception occurs
}
}
@Override
public int compareTo(Contact c){
return this.name.compareTo(c.getName());
}
public boolean equals(Object o){
Contact c = (Contact)o;
return this.name.equals(c.getName());
}
public void addContact(Contact c){
LinkedList<Contact> list = new LinkedList<Contact>();
for (Contact contact: contacts){
list.add(contact);
}
}
public Contact[] getContacts(){
return contacts.toArray(new Contact[0]);
}
public int hashCode(){
return name.hashCode();
}
public String toString(){
return this.name;
}
}
答案 0 :(得分:2)
答案就在Collator.java:
public int compare(Object o1, Object o2) {
return compare((String)o1, (String)o2);
}
这对我来说不是很明显,但为什么你在地球上传递自己的Collator? 你在处理Non ascii吗?
你在这里也有一个不一致的地方:compareTo()== 0应该和equals()一样,特别是因为在这两种情况下,你似乎唯一关心的是'name'
因此,一方面,您声明要删除相同的条目,因此您使用比较身份但是您使用的Collator肯定会产生与equals不一致的结果。
如果你想要的只是删除冗余而不是跳过Collator并且使用没有Collator的HashSet或TreeSet
或者,如果你必须使用整理的名称,那么使用
TreeMap<String,Contact> contacts = new TreeMap<String,Contact>(Collator.getInstance());
contacts.put(contact.getName(),contact);
然后您可以使用:
Collection<Contact> uniqueContacts = contacts.values();
答案 1 :(得分:-1)
c.getName()返回一个String然后用这个调用equals ..所以String被传递给equals ...
第一行等于尝试将String转换为Contact ... Boom
compare方法将在它尝试比较的对象上调用equals。