ClassCastException - finde den Fehler nicht :-(

Oliver Gierke

Erfahrenes Mitglied
Hallo zusammen,

ich habe folgende zwei Klassen:

Code:
import java.util.Set;
import java.util.TreeSet;

public class Student implements GenericStudent {

	private String name = null;
	private int id;
	private Set exams = new TreeSet();
	
	public Student(String studName, int studId) {
		name = studName;
		id = studId;
	}

	public int getStudentId() {
		return id;
	}

	public Set getExams() {
		return exams;
	}

	public boolean addExam(Exam exam) throws NullPointerException {
		if (exam==null) throw new NullPointerException();
		boolean notin = !(exams.contains(exam));
		exams.add(exam);
		if (!exam.getParticipants).contains(this)) {
			exam.addParticipant(this);
		}	
		return notin;
	}

	public boolean removeExam(Exam exam) throws NullPointerException {
		if (exam==null) throw new NullPointerException();
		boolean in = exams.contains(exam);
		exams.remove(exam);
		if (exam.getParticipants().contains(this)) {
			exam.removeParticipant(this);
		}
		return in;
	}	
}
Code:
import java.util.Set;
import java.util.TreeSet;

public class Exam implements GenericExam {
	
	private String semester;
	private String course;
	private Set participants = new TreeSet();

	public Exam(String examCourse, String examSemester) {
		semester = examSemester;
		course = examCourse;
	}

	public String getSemester() {
		return semester;
	}

	public String getCourse() {
		return course;
	}

	public boolean addParticipant(Student student) throws NullPointerException {
		if (student==null) throw new NullPointerException();
		boolean notin = !(participants.contains(student));
		participants.add(student);

		if (!student.getExams().contains(this)) {
			student.addExam(this);
		}
		return notin;
	}

	public boolean removeParticipant(Student student) throws NullPointerException {
		if (student==null) throw new NullPointerException();
		boolean in = participants.contains(student);
		participants.remove(student);
		if (student.getExams().contains(this)) {
			student.removeExam(this);
		}
		return in;
	}

	public Set getParticipants() {
		return participants;
	}

}

Sinn der Sache soll sein, Studenten und Klausuren zu verwalten. Ich bin jetzt zusaätzlich zur Aufgabenstellung auf die Idee gekommen, dass, sobald man einen Studenten für eine Klausur "anmeldet", dieser auch in die Teilnehmerliste der Klausur eingetragen wird. Ich schreib dazu die Klausur in die Klausurenliste des Studenten und rufe für den Fall, dass er noch nicht in der Teilnehmerliste der Klausur steht die Methode addExam auf. Diese soll nun den Studenten in die Teilnehmerliste eintragen.

Für den Fall eines umgekehrten Aufrufs (Exam.addParticipant) soll natürlich auch geprüft werden, ob die Klausur schon in die Klausurenliste des Studenten eingetragen wurde.

Leider bekomme ich beim Versuch, dem Studenten eine Klausur hinzuzufügen in der methode addParticipant bei der if-Abfrage student.getExams().contains(this) eine ClassCastException. Versteh nur nicht ganz warum? student.getExams() liefert ein Set, this ist vom Typ Exam, als ein Objekt.

Kann wer helfen?

Danke

Ollie
 
Hallo!

Ein TreeSet ist eine implementierung des Set Interfaces welche versucht die ihr inne Wohnenden Elemente in einer gewissen Ordnung zu halten. Zu diesem Zweck sollten alle darin abgelegten Elemente das Comparable Interface Implementieren um dies sicherzustellen:

Code:
/*
 * Created on 02.02.2005@19:37:59
 *
 * TODO Licence info
 */
package de.tutorials;

import java.util.Set;
import java.util.TreeSet;

/**
 * @author Administrator
 *
 * TODO Explain me
 */
public class Student implements GenericStudent, Comparable {

    private String name = null;

    private int id;

    private Set exams = new TreeSet();

    public Student(String studName, int studId) {
        name = studName;
        id = studId;
    }

    public int getStudentId() {
        return id;
    }

    public Set getExams() {
        return exams;
    }

    public boolean addExam(Exam exam) throws NullPointerException {
        if (exam == null)
            throw new NullPointerException();
        boolean notin = !(exams.contains(exam));
        exams.add(exam);
        if (!exam.getParticipants().contains(this)) {
            exam.addParticipant(this);
        }
        return notin;
    }

    public boolean removeExam(Exam exam) throws NullPointerException {
        if (exam == null)
            throw new NullPointerException();
        boolean in = exams.contains(exam);
        exams.remove(exam);
        if (exam.getParticipants().contains(this)) {
            exam.removeParticipant(this);
        }
        return in;
    }

    /* (non-Javadoc)
     * @see java.lang.Comparable#compareTo(java.lang.Object)
     */
    public int compareTo(Object o) {
        if(o == null){
            return 1;
        }
        //....
        if (o instanceof Student) {
            Student s = (Student) o;
            return this.name.compareTo(s.name);
        } else {
            return 0;
        }
    }
}

Dann bekommst du auch keine ClassCastException mehr...

Gruß Tom
 
dank dir... funktioniert jetzt. aber mal ne prinzipielle frage: wenn ich also TreeSet benutze muss ich compareTo immer selber implementieren?

In meinem Fall schmeiße ich Student Objekte in dieses TreeSet und muss deshalb für irgendeine Form von korrekter sortierung sorgen, richtig? (Nur damit ich das auch versteh ;-)

Danke nochmal

Ollie
 
nur rein informativ:

Die Collections in Java dienen stets verschiedenen Anwendungsfällen (=kling logisch :p ).

Wenn Du eine Sortierung brauchst, mußt Du Comparable-Objekte benutzen (siehe oben) oder dem TreeSet einen eigenen Comparator mitgeben, den das TreeSet dann für alle Objekte benutzt, damit könntest Du Dir die Methode für jedes Objekt sparen.

Ohne Sortierung könntest Du eine Hash-Collection (z.B. Hashtable oder HashSet) nutzen, die verwalten beliebige Objekte anhand des Hash-Codes (Methode hashCode(), die jedes Objekt hat, aber sinnvollerweise bei eigenen Objekten überschrieben werden sollte). Für Sets wäre dann noch die equals()-Methode zu erwähnen, die stets true geben soll, wenn Deine Klasse gleich Deiner anderen Klasse sein soll, denn Sets sortieren Dupletten aus.

Das soll nun mal als kleiner Einblick genügen - wenn Du noch Fragen zu den Collections hast?
 
Zurück