Collections Verkettete Listen und Fußball...

dudsen

Mitglied
Hi,

Habe wieder mal ein Problem mit einer Verketteten Liste zur Klausurvorbereitung.
Ich bekomme bei meiner insert() Methode eine Null Pointer Exception, und verstehe einfach nicht warum.

Gegeben ist eine vorher erstellte verkettete Liste die mit Namen und erzielten Toren so aussieht:

Klose 14-->Rahn 10-->Beckenbauer 5-->Conen 4 -->null

Die Klasse mit Methoden:

Java:
public class WMListe {
	private Spieler spieler;	//data of 1 element
	private WMListe next;		//pointer to the following object
	WMListe first;			//points to the head of list
	WMListe oldfirst;

	public WMListe(Spieler s) {
	spieler = s;
	next = null;
	}
	
	public WMListe(String datei) {
		first = null;
		oldfirst = null;
	
		In input = new In(datei);
		
		while(!input.isEmpty()){
			String name = input.readString();
			int tore = input.readInt();
			spieler=new Spieler(name,tore);
			
			if(first==null){
				first=new WMListe(spieler);
				first.next=null;
			}
			else{
				oldfirst=first;
				first=new WMListe(spieler);
				first.next=oldfirst;
			}
			
			
		}
	}
	
	public static WMListe insert(WMListe liste, Spieler s){
		WMListe current=liste;
		WMListe insert=new WMListe (s);
		
		while(current!=null){
			if(s.getTore()>=liste.spieler.getTore()){
				insert.next=liste;
				liste=insert;
			}
			// Zeile 131, hier meckert er rum mit einer Null Pointer Exception
			else if(s.getTore()<current.spieler.getTore() && s.getTore()>=current.next.spieler.getTore()){
				insert.next=current.next;
				current.next=insert;
			}
			else if(s.getTore()<current.spieler.getTore() && current.next==null){
				current.next=insert;
			}
			current=current.next;
		}
		return liste;
	}
	
	
		
	public String toString(){
	String s = "";

		//1) reversing the current list
		WMListe current=first;
		WMListe previous=null;
		WMListe forward;
		
		while(current!=null){
			forward=current.next;
			current.next=previous;
			previous=current;
			current=forward;
		}
		
		//concats the current list to a String
		for(WMListe x=previous;x!=null;x=x.next){
			s+=x.spieler + "\n";
		}
		
		return s;
	}
	
	

	//zum testen
	public static void main(String[] args) {
		
		String datei= "Spielerdaten.txt";
		WMListe liste= new WMListe(datei);
		
		Spieler klinsi= new Spieler ("Kliensmann",11);
		liste=insert(liste,klinsi);
		
		System.out.print(liste);
		

	}
	
}

Und noch die Klasse Spieler:
Java:
public class Spieler { 
        String name;	// Name des Spielers 
	int tore;	       // Anzahl der Tore

	public Spieler(String name, int tore) {
		this.name = name;
		this.tore = tore;
	} 
	
	public String getName() {
		return name;
	}
	
	public int getTore() {
		return tore; 
	}
	
	public String toString() {
		return name + " Tore:" + tore;
	}
}

Und das Erbrochene der Konsole:

Exception in thread "main" java.lang.NullPointerException
at WMListe.insert(WMListe.java:132)
at WMListe.main(WMListe.java:178)


Ich blicks nicht. Finde keinen Fehler in der insert Methode. Warum sollte current.next auf Null Zeigen? Ist doch am Anfang auf das Selbe Objekt wie Liste gesetzt? Oder hab ich mal wieder einen offensichtlichen Denkfehler?

Für Hilfe sehr Dankbar 🙂

.d
 
Zuletzt bearbeitet:
Nur kurz überflogen:
// Zeile 131, hier meckert er rum mit einer Null Pointer Exception
else if(s.getTore()<current.spieler.getTore() && s.getTore()>=current.next.spieler.getTore()){

Ich nehme an, "current.next" ist null (üblicherweise am Ende der Liste...)
 
Finde die Implementierung auch etwas fragwürdig.
insert sollte eine Methode auf einem Listen-Objekt sein, nicht unbedingt statisch.
Klar das funktioniert so, ist aber nicht sonderlich schön.
Die Sichtbarkeiten der Member-Variablen sind demzufolge auch ein No-Go.

Eine Sortieren-Funktion hingegen kannst du statisch auslagern, da diese nur das Objekt modifizieren soll.

Die Vorteile sind einfach eine erheblich bessere Übersichtlichkeit.
Als Anfänger neigt man dazu alles in große unübersichtliche Code-Blöcke zu packen, war bei mir ja auch so.
Versuche immer in "Problemen" zu denken. Eine Methode für ein Problem.
 
Danke schonmal für die fixen Antworten,

OK, war ein wenig unglücklich nicht die ganze Klasse zu Posten... Eintrag wurde oben überarbeitet.
next pointet eigentlich nicht auf null, das ist beim anlegen der Liste ( siehe zweiten Konstruktor) jeweils festgelegt.

Ausgabe auf der Konsole ist ebenfalls richtig, also stimmen die jeweiligen next pointer.
Denke ich doch mal.

Mit den Festlegungen in der insert_Methode:

WMListe current=liste;

...

else if(s.getTore()<current.spieler.getTore() && s.getTore()>=current.next.spieler.getTore()){

Sollte es doch normalerweise gehen oder nicht?

Hoffentlich kann jemand mir mein Brett vorm Kopf wegnehmen. Das nervt :rtfm:

.d
 
Hehe,

habe so die Vorahnung das ich dir ins Messer laufe.

Nach meinem Verständnis passiert das im Konstruktor. Um genau zu sein im Zweig der if-Anweisung:

oldfirst=first;
first=new WMListe(spieler);
first.next=oldfirst;

Dort werden doch den jeweiligen "next" Variablen der Objekte das darauf folgende zugewiesen.
Also mit first.next=oldfirst;

Ja? Ne?
 
Aufpassen.
Java:
else if(s.getTore()<current.spieler.getTore() && s.getTore()>=current.next.spieler.getTore()){

Gehen wir davon aus du hast folgende Liste (ohen SpielerNamen) :

8 Tore / 5 Tore / 2 Tore / null

Jetzt willst du 1 Spieler mit 1 Tor einfügen... läufst einige mal durch deine schleifen und kommst zu folgendem Stand:

current = 2 Tore!
jetzt befüllen wir einmal dein IF :
Code:
if(s.getTore()<current.spieler.getTore() && s.getTore()>=current.next.spieler.getTore()){
if(  1         <            2                  &&       1     >=   2 hat keinen nachfolger..next ist nulll ){
gemerkt?

nebenbei wozu braucht man "oldFirst" ???:L

Gehen wir davon aus du hast "nur" First.
So würde folgender code ausreichen :
Code:
neuerEintrag.next = first;
first = neuerEintrag;

OldFirst wär somit überflüssig.
Auch verstehe ich das Design deiner Liste nicht ganz.
Wenn man es Bildlich beschreibt, so ist deine Liste ein Buch mit 1 Seite.
Und immer wenn du etwas "hinzufügen" willst, so packst du 1 neues Buch mit 1 Seite in dein Buch...

Wie wäre es die WmListe als "kopf" zu verwenden, wo nur die Referenz auf z.B. den 1. und den letzen eintrag enthalten sind. Natürlich mit allen wichtigen Methode. So würdest du es dir ersparen immer ein neues Buch in das Buch zu legen...

Code:
Buch -> Zeigt auf Seite 1 
Buch -> Zeigt auf die letzte Seite

Seite -> Enthält 1 Spieler
Seite -> Zeigt auf nächste Seite

Spieler -> Steht auf 1 Seite
 
Zuletzt bearbeitet:
Java:
    public WMListe(String datei) {
        first = null;
        oldfirst = null;
    
        In input = new In(datei);
        
        while(!input.isEmpty()){
            String name = input.readString();
            int tore = input.readInt();
            spieler=new Spieler(name,tore);
            
            if(first==null){
                first=new WMListe(spieler);
                first.next=null;
            }
            else{
                oldfirst=first;
                first=new WMListe(spieler);
                first.next=oldfirst;
            }
            
            
        }
    }

first ist immer null. Deswegen funktioniert das hier auch nicht bzw. else Block wird nie aufgerufen.

Nochmal was anderes:
Mein Vorposter hat schon recht. Wenn du eine verkettete Liste baust so definiere ein Element mit prev, next Variablen.
Die Listen-Klasse muss nur "first" kennen. Jede Klasse Element kennt seinen Vorgänger und Nachfolger. Ein Element hat dann in deinem Fall einen Spieler und prev auf voriges Element mit Spieler sowie next auf nächstes Element mit Spieler.

Java:
public class MyElement{

private Spieler spieler;
private MyElement next;
private MyElement prev;

...dein Code...

}
 
Zuletzt bearbeitet:
Sooo, danke nochmal ihr 2 für die investierte Zeit.

100%ig klar ist es immer noch nicht, aber besser als gestern.

first ist immer null. Deswegen funktioniert das hier auch nicht bzw. else Block wird nie aufgerufen.

Nope. in der ersten if-Verzweigung wird first ein Spieler zugewiesen, sodass bei dem 2ten Durchlauf der while Schleife der else Zweig ausgeführt wird. Der Konstruktor funktioniert ja auch soweit und die Liste wird auch ausgegeben.

Mit der prev- Variable ist definitiv besser,da hast du Recht. hab ich bei einer anderen Aufgabe auch mal eingebaut.

Ich probier nochmal das ganze neu zu implementieren. Meine Kommolitonen haben heute auch gemeint das dieser Teil der Aufgabe mit den Auflagen der Hass war.

Anyway, danke

Ich setz mich nochmal davor :rtfm:

laterssssss
 
Ich würde noch mehr Aufgaben dieses Profs Online stellen....
Dadurch werden sicher die Klausuren immer leichter....MANN MANN MANN
 

Neue Themen


Zurück
Oben