Prosta kolekcja i ClassCastException

0

Witam
Mam mały problem z ogarnięciem kolekcji. Napisalem mały "program" aby zobaczyć jak to wszystko działa, jednak po dobrnięciu do linii z sorter.add(pierwsze) wywala mi błąd ClassCastException. Eclipse wyświetla taki oto komuniakt:

Exception in thread "main" java.lang.ClassCastException: Dane cannot be cast to java.lang.Comparable 
         at java.util.TreeMap.compare(Unknown Source) 
         at java.util.TreeMap.put(Unknown Source) 
         at java.util.TreeSet.add(Unknown Source) 
         at LLL.main(LinkedListTest.java:31)

Jak się tego pozbyć ? Kod poniżej:

public class LLL 
{ 
    @SuppressWarnings("unchecked") 
public static void main(String[] args) 
    { 
            StreamTokenizer st= new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); 
            PrintWriter wyj= new PrintWriter(System.out); 
            
            String nazwisko=""; 
            String imie=""; 
            
            wyj.printf("Podaj nazwisko i imie ").flush(); 
            
            try { 
                 st.nextToken(); 
                 nazwisko=st.sval; 
                 
                 st.nextToken(); 
                 imie=st.sval;       
            }catch (IOException e){ 
                          e.printStackTrace(); 
                    }    
            Dane pierwsze=new Dane(nazwisko, imie); 

            SortedSet<Dane> sorter = new TreeSet<Dane>(); 
            sorter.add(pierwsze); 
    } 
}

I klasa Dane:

public class Dane {       
         String nazw; 
         String imi; 
         
         Dane(String n, String im){ 
                 nazw=n; 
                 imi=im; 
         } 
}
 
0
  1. Po co tam wsadzasz SuppressWarnings?
  2. Jak chcesz mieć SortedSeta to elementy muszą implementować Comparable albo musisz podać odpowiedniego Comparatora w wywołaniu konstruktora. Jak niby inaczej elementy mają być porównane?
0
  1. Eclipse automatycznie mi to dorzucił
  2. Rozumiem że chodzi o zaimplementowanie Comparable w klasie Dane. Zrobiłem to i wyświetla bład dopóki nie dopiszę metody compareTo()...
    Dałoby się jakoś to tak zaimplementować beez tej metody ?
0
  1. Nie dorzucił tylko podpowiedział.
  2. Ponawiam pytanie: Jak TreeSet ma ci posortować elementy jeżeli nie podasz mu funkcji porównującej? Jeśli dostanie dwa obiekty typu odpowiednio: Krzesło i Stolik, to który będzie "większy" (zakładając, że nie ma metody compareTo)?
0
  1. Teraz do mnie dotarło, nie ma to jak zilustrować problem ;p
    Chciałbym żeby sortowało wg nazwiska.
1

implements Comparable<Dane>
...
int compareTo(Dane that) {
return nazwisko.compareTo(that.nazwisko);
}

Z tym, że powinieneś dodać jeszcze zabezpieczenie przed nullem.

0

A mógłbyś mi napisać gdzie to konkretnie (która klasa itp) zaimplementować ?
Pytanie może głupie, ale jeszcze nie ogarniam tych kolekcji ...

0

class Dane implements Comparable<Dane> {
blebleble
int compareTo(Dane that) {
return nazwisko.compareTo(that.nazwisko);
}
}

0

A gdybym chciał posortowaną kolekcję wg. nazwiska posortować teraz g. imienia ?
Domyślam się,żeby dopisać komparator do klasy Dane taki sam jak dla nazwiska, tylko, że zamiast "nazwisko" wpisać "imie".
Tylko jak mu wskazać,mając 2 komparatory w klasie, że chcę posortować wg imienia ?

0

Źle się domyślasz. Musisz dostarczyć jeden komparator, a w nim sprawdzić czy nazwiska są różne, jeżeli tak to zwrócić wynik porównania nazwisk, jeżeli są różne to zwrócić wynik porównania imion.

0

@airborn, niekoniecznie. Zakładasz, że autor chce sortować wg nazwiska, a jeśli nazwiska są identyczne to wg imienia. Pytanie sugeruje inny problem, on chce kolekcje sortować wg kilku niezależnych kryteriów: czasem wg nazwiska, czasem wg daty urodzenia,.... Wtedy trzeba użyć metody sort(kolekcja, komparator) używając różnych komparatorów.

0

Jeśli chcesz składać Comparatory to możesz sobie zrobić kompozytowego Comparatora :] Typu:

final public class Comparator2<T> implements Comparator<T> {
private Comparator<T> comparator1;
private Comparator<T> comparator2;
public Comparator2(Comparator<T> comparator1, Comparator<T> comparator2) {
this.comparator1 = comparator1;
this.comparator2 = comparator2;
}
int compare(T fst, T snd) {
  int result = comparator1.compare(fst, snd);
  if (result == 0) {
    result = comparator2.compare(fst, snd);
  }
  return result;
}
bool equals(Object that) {
  if (!that instanceof Comparator2) {
    return false;
  }
  Comparator2 thatC = (Comparator2) that;
  return comparator1.equals(thatC.comparator1) && comparator2.equals(thatC.comparator2);
}
}

Wtedy możesz zrobić: new Comparator2(comparator po nazwisku, comparator po imieniu); a nawet coś takiego jak new Comparator2(comparator po nazwisku, new Comparator2(comparator po imieniu, comparator po roku urodzenia)); itd itp

Kod pisałem z palca, w ogóle nie testowany.

0

Można też bez komparatorów.

class Dane implements Comparable<Dane> 
{
    int order;
    ...
    public void setOrder(order);
    {
        this.order=order;
    }
    int compareTo(Dane that) 
   {
       switch(order)
       {
           case ...
             return nazwisko.compareTo(that.nazwisko);
             break;
           case ... 
       }
   }
} 

A potem przed sortowaniem wywoływać metodę setOrder() z odpowiednim argumentem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1