1

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

当我尝试将 Contact[] 中的 Contact 对象(请参阅下面的 setContacts() 方法)添加到 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)

我不明白的是,在我构建的任何类中,我都没有尝试将任何东西转换为字符串。下面是我的整个联系课程。

有没有人看到任何错误或看到异常发生的原因?

如果有人告诉我还有什么相关的,我很乐意发布更多代码。我不知道还有什么重要的看。提前致谢。

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;
    }




}
4

2 回答 2

2

答案就在 Collat​​or.java 中:

public int compare(Object o1, Object o2) {
return compare((String)o1, (String)o2);
}

这对我来说并不是很明显,但你到底为什么要传递你自己的 Collat​​or?你在处理非ascii吗?

您在这里也有不一致之处: compareTo() == 0 应该与 equals() 相同,尤其是因为在这两种情况下,您似乎唯一关心的是“名称”

因此,一方面您声明要删除相同的条目,因此您使用比较身份,但随后您使用的 Collat​​or 肯定会产生与 equals 不一致的结果。

如果您想要的只是删除冗余而不是跳过 Collat​​or 并使用没有 Collat​​or 的 HashSet 或 TreeSet

或者,如果您必须使用 Collat​​ed names 然后使用

TreeMap<String,Contact> contacts = new TreeMap<String,Contact>(Collator.getInstance());
contacts.put(contact.getName(),contact);

然后你可以使用:

Collection<Contact> uniqueContacts = contacts.values();
于 2013-04-18T19:01:28.127 回答
-1

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

等号的第一行尝试将字符串转换为联系人...繁荣

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

于 2013-04-18T18:48:59.873 回答