Problem z kodem - Kolekcje

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();
	}
}
0

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

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:

Osoba@6bbc4459/n

0

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

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.

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();
	}
}
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/javase/6/docs/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.

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

0

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

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