Problem z kodem - Kolekcje

Odpowiedz Nowy wątek
2011-08-15 18:18
0

Witam, poniższy kod mi nie działa ma wypisać kolekcję osób zatrudnionych. Klasa Osoba, klasa biuro i startowa. Co tutaj jest źle, jak to poprawić? Błąd na konsoli to:

//Exception in thread "main" java.lang.ClassCastException: Osoba cannot be cast to java.lang.Comparable
at java.util.TreeMap.put(Unknown Source)
at java.util.TreeSet.add(Unknown Source)
at Biuro.zatrudnij(Biuro.java:19)
at Mainowa.main(Mainowa.java:8)//

Czepia się metody zatrudnij i jej wywołania w main. Proszę o pomoc.

//////////////////////// Klasa Osoba

import java.io.Serializable;
 
/*
 * Zdefiniuj klase o nazwie Osoba, która:
(a) posiada konstruktor przyjmujacy dwa argumenty: nazwisko i rok urodzenia, rok między 1800, 2000 jak nie to zwróć wyjątek
(b) implementuje interfejs Serializable.
 */
public class Osoba implements Serializable {
    String nazw;
    int rok;
 
    public Osoba (String n, int ru){
        this.rok=ru;
 
        try {
            if (this.nazw != null){
                this.nazw=n;
            }
        } catch (NullPointerException e){
            System.out.println("Nie znaleziono nazwiska");
        }
        try {
            if (this.rok>1799 && this.rok<2001){
                this.rok=ru;
            }
        } catch (AssertionError e){
            System.out.println("Niepoprawna wartosc roku urodzenia " +
                    "(oczekiwano wartosci z przedziału od 1800 do 2000)");
        }
    }
}

//////////////////////// Klasa Biuro

import java.util.TreeSet;
 
public class Biuro {
    TreeSet<Osoba>o;
 
    public Biuro(){
        this.o=new TreeSet<Osoba>();
    }
 
    void wypisz(){
        for (Object os: o){
            System.out.println (os+"/n");
        }
    }
 
    TreeSet<Osoba> zatrudnij(String nazw, int rok){
        Osoba os = new Osoba(nazw, rok);
        o.add(os);
        return o;
    }   
}

//////////////////////// Klasa "Main"

public class Mainowa {
    public static void main(String[] args){
        Osoba os=new Osoba("Gienek", 1999);
        Biuro b=new Biuro();
        b.zatrudnij("Kowalski", 1999);
        b.zatrudnij("Nowak", 1965);
        b.wypisz();
    }
}

Pozostało 580 znaków

2011-08-15 18:27
0

TreeSet wymaga albo Comparatora podanego w konstruktorze, albo by elementy implementowały Comparable.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.

Pozostało 580 znaków

2011-08-15 19:21
Patryk_1425
0
Wibowit napisał(a)

TreeSet wymaga albo Comparatora podanego w konstruktorze, albo by elementy implementowały Comparable.

Program zadziałał, choć nie do końca, bo program wypisał coś takiego:

[email protected]/n

Pozostało 580 znaków

2011-08-15 19:34
bo
0

Wypisał, to co sobie zażyczyłeś. Jeśli masz inne życzenie, to nadpisz metodę public String toString() w klasie Osoba.

Pozostało 580 znaków

2011-08-15 19:49
Patryk_1425
0
bo napisał(a)

Wypisał, to co sobie zażyczyłeś. Jeśli masz inne życzenie, to nadpisz metodę public String toString() w klasie Osoba.

Okej, dzięki. Zadziałało, ale jeszcze nie działa w momencie gdy trzeba wyrzucić kilka elementów kolekcji, a on wyrzuca na ekran tylko 1 i nic więcej. I nie działa Mi jeszcze taka opcja, że jeśli podam null jako nazwisko albo wiek jeśli nie mieści się w przedziale 1800-2000 to ma wyrzucać błąd i kończyć. Jak te dwie rzeczy poprawić w kodzie.

Pozostało 580 znaków

2011-08-15 21:51
0

Mój kod wygląda teraz tak jak poniżej. Program nie działa w momencie gdy trzeba wyrzucić kilka elementów kolekcji, a on wyrzuca na ekran tylko 1 i nic więcej. I nie działa Mi jeszcze taka opcja, że jeśli podam null jako nazwisko albo wiek jeśli nie mieści się w przedziale 1800-2000 to ma wyrzucać błąd i kończyć. Jak te dwie rzeczy poprawić w kodzie. Proszę o pomoc i pytanie czy w ten sposób miałem nadpisać metode toString() ?

import java.io.Serializable;
 
/*
 * Zdefiniuj klase o nazwie Osoba, która:
(a) posiada konstruktor przyjmujacy dwa argumenty: nazwisko i rok urodzenia,
(b) implementuje interfejs Serializable.
 */
public class Osoba implements Serializable, Comparable {
    String nazw;
    int rok;
 
    public Osoba (String n, int ru){
        this.rok=ru;
 
        try {
            if (this.nazw == null){
                this.nazw=n;
            }
        } catch (NullPointerException e){
            System.out.println("Nie znaleziono nazwiska");
        }
        try {
            if (this.rok>1799 && this.rok<2001){
                this.rok=ru;
            }
        } catch (AssertionError e){
            System.out.println("Niepoprawna wartosc roku urodzenia " +
                    "(oczekiwano wartosci z przedziału od 1800 do 2000)");
        }
    }
 
    public String toString(){
        return ("Osoba "+nazw+" Rok "+rok);
    }
 
    @Override
    public int compareTo(Object os) {
        // TODO Auto-generated method stub
        return 0;
    }
}
 
//////////////
import java.util.TreeSet;
 
public class Biuro implements Comparable{
    TreeSet<Osoba>o;
 
    public Biuro(){
        this.o=new TreeSet<Osoba>();
    }
 
    void wypisz(){
        for (Object os: o){
            System.out.println (toString());
        }
    }
 
    public String toString(){
        return ("Kolekcja: \n"+o);
    }
 
    TreeSet<Osoba> zatrudnij(String nazw, int rok){
        Osoba os = new Osoba(nazw, rok);
        o.add(os);
        return o;
    }
 
    @Override
    public int compareTo(Object arg0) {
        // TODO Auto-generated method stub
        return 0;
    }   
}
 
//////////////////////
public class Mainowa {
    public static void main(String[] args){
        Osoba os=new Osoba("Gienek", 1699);
        Biuro b=new Biuro();
        b.zatrudnij("Pola", 1699);
        b.zatrudnij("Nowak", 1965);
        b.wypisz();
    }
}

Pozostało 580 znaków

2011-08-15 22:50
0

Program nie działa w momencie gdy trzeba wyrzucić kilka elementów kolekcji, a on wyrzuca na ekran tylko 1 i nic więcej.

Bo compareTo zawsze daje 0. A co to oznacza? Wystarczy uruchomić mózg zamiast siać 100 pytań na forum i poczytać JavaDoc:

http://download.oracle.com/ja[...]cs/api/java/util/TreeSet.html napisał(a)

Note that the ordering maintained by a set (whether or not an explicit comparator is provided) must be consistent with equals if it is to correctly implement the Set interface. (See Comparable or Comparator for a precise definition of consistent with equals.) This is so because the Set interface is defined in terms of the equals operation, but a TreeSet instance performs all element comparisons using its compareTo (or compare) method, so two elements that are deemed equal by this method are, from the standpoint of the set, equal. The behavior of a set is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Set interface.

0 oznacza dla TreeSeta, że aktualny obiekt jest taki sam jak podany w parametrze. Jeżeli przy dodawaniu obiektu do TreeSeta istnieje inny, który daje 0 dla metody compareTo, to TreeSet wyrzuca tego innego.

I nie działa Mi jeszcze taka opcja, że jeśli podam null jako nazwisko albo wiek jeśli nie mieści się w przedziale 1800-2000 to ma wyrzucać błąd i kończyć.

Nie działa bo nigdzie jej nie ma. Poza tym NPE się dostaje, gdy wywołujesz metodę na nullu, a nie gdy go z czymś porównujesz. AssertionError jest przy assertach a nie zwykłych ifach. Jeśli chcesz propagować jakiś wątek bez wrzucania go do throwsów w każdej metodzie w hierarchii, to niech dziedziczy on po RuntimeException. Innymi słowy, rzucania wyjątków typu RuntimeException (lub pochodnych) nie trzeba deklarować po "throws" w deklaracji funkcji.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.

Pozostało 580 znaków

2011-08-15 23:06
0

Bo metoda compareTo zawsze zwraca u ciebie 0, więc każdy obiekt Osoba jest traktowany jako ten sam (a w zbiorach obiekty muszą być unikalne). Jeśli chcesz zbiór posortowany, zaimplementuj sensownie compareTo, w przeciwnym wypadku użyj HashSeta. Poza tym, przechwytujesz wyjątki, które nigdy nie powstają.

public Osoba (String n, int ru){
    if (n == null) {
        throw new IllegalArgumentException("Nie znaleziono nazwiska");
    }
    if (ru < 1800 || ru > 2000) {
        throw new IllegalArgumentException("Niepoprawna wartosc roku urodzenia " +
                                        "(oczekiwano wartosci z przedziału od 1800 do 2000)";
    }
    nazw = n;
    rok = ru;
}

Pozostało 580 znaków

2011-08-16 00:07
0

Czyli krótko. W konstruktorze jeśli chce się wywołać błąd to trzeba to zrobić tak jak to zrobił iooi a w metodzie można try-catch?

Pozostało 580 znaków

2011-08-16 09:29
0

Ale try-catch-finally nie służy do wywoływania błędów, tylko do ich obsługi... Poczytaj o wyjątkach


Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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