2013-04-18 4 views
1

У меня есть контакт класса, который я привел ниже. Я хочу, чтобы каждый объект Contact имел список других контактов. Я выбрал TreeSet, потому что я хотел бы избежать дублирования контактов в том же списке. Класс My Contact реализует Comparable и имеет построенный метод compareTo(), который сравнивает переменные String экземпляра. Я понимаю, что метод compareTo используется при добавлении в TreeSet, потому что добавленные элементы сразу сортируются.ClassCastException, когда Treeset.add(), несмотря на реализацию, сопоставимую с методом compareTo

Когда я пытаюсь добавить контактный объект из контакта [] (см. Мой метод 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; 
    } 




} 

ответ

2

Ответ прямо здесь, в Collator.java:

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

Это не сразу очевидно для меня, но почему на Земле вы переходящая в своем собственном Collator? Вы имеете дело с Non ascii?

Вы также несогласованность здесь: CompareTo() == 0 должен быть таким же, как равные() тем более, что в обеих случаях единственным, что вы, кажется, заботятся о том, «имя»

Таким образом, на с одной стороны, вы заявляете, что хотите удалить идентичные записи и, таким образом, используете сравнительную идентификацию, но затем используете Collator, который может определенно создавать противоречивые результаты с равными.

Если все вы хотите удалить избыточность, чем пропустить Collator и либо использовать HashSet или TreeSet, не Collator

В качестве альтернативы, если вы должны использовать имена с разборкой затем использовать

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

Вы можете использовать:

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

Я полностью не понял использование Collator. Мне не нужен Collator, и мне просто нужен список без дубликатов, который может быть организован значениями String. Удаление части 'Collater.getInstance()' исправляло все это. Благодарю вас. –

+0

Для наглядности: список и набор имеют существенные отличия. Списки индексируются (list.get (0);), а наборов нет. Наборы содержат только уникальные элементы. Их порядок итерации зависит от реализации. Наборы требуют некоторых накладных расходов, поскольку они должны проверять личность каждого объекта, вставленного против текущего набора, для поддержания отсутствия дубликатов. В списках нет такого требования. –

-1

c.getName() возвращает строку, а затем вы называете равных с этим .. поэтому строка передается равна ...

первая линия равных попытаться бросить строку в Контакт ... Boom

Метод сравнения будет называть equals на объекте, который он пытается сравнить.

+0

Равно ни в коем случае не вызывается в сортировке/сравнении. Посмотрите на трассировку стека. Кроме того, как compareTo(), так и equals() используют «имя», которое является строкой. Пожалуйста, см. Мой пост ниже –

+0

@chris: вы правы, у меня было предположение о том, что были вызваны равные сравниваемые объекты. моя вина! – Cygnusx1

+0

Я только что проверил и вернулся, чтобы задать больше вопросов, и вот они уже получили ответ!haha –