Generics ... VerketteteListe<T> extends ArrayList<T>

I2oxxi

Mitglied
Also ich soll eine eigene Verkettete Liste schreiben, mit diesem Generics gedöhns ^^ Is grad neu in der Vorlesung. Dazu noch ne Klasse ListenElement<T>.
Soweit sogut, hab mich im Inet schlau gemacht, was gefunden und mal angefangen.
Verkettete Listen sollen ja Vorgänger und Nachfolger haben, hab mir das ganze dann so vorgestellt:

ListenElement<T>
Code:
package aufgabe1;

public class ListenElement<T> {
	
	private T object;
	private ListenElement<T> nachfolger;
	private ListenElement<T> vorgänger;
	
	public ListenElement()
	{
	
	}
	
	public ListenElement(T object)
	{
		this.object=object;
	}
	
	public ListenElement<T> getVorgänger()
	{
		return this.vorgänger;
	}
	
	public ListenElement<T> getNachfolger()
	{
		return this.nachfolger;
	}
	
	public void setVorgänger(ListenElement<T> element)
	{
		this.vorgänger=element;
	}
	
	public void setNachfolger(ListenElement<T> element)
	{
		this.nachfolger=element;
	}

}

Dürfte denk ich passen. Das Problem jetzt mit der Liste selber:

VerketteteListe<T>:
Code:
package aufgabe1;

import java.util.*;

public class VerketteteListe<T> extends AbstractList<T> {

	private ListenElement<T> start;
	private ListenElement<T> ende;
	
	public VerketteteListe()
	{
		start = new ListenElement<T>();
		ende = new ListenElement<T>();
		start.setVorgänger(null);
		start.setNachfolger(ende);
		ende.setVorgänger(start);
		ende.setNachfolger(null);
	}
	

	public int size() 
	public boolean add(T element)
	public void add(int index, T element)
	public void clear()
	public T get(int index)
	public T remove(int index)
	public T set(int index, T element)

}
Rümpfe hab ich weggelassen, sind imo eh leer.
Am Anfang hat die Liste ja Anfang und Ende (habs im Inet so gelesen).
Vorm Anfang is nix (null) und nach dem Ende halt au nix.
Aber wie geht nun weiter? Wie fülle ich die Rümpfe?
bei size() habe ich mir z.B. gedacht, sowas wie gehe immer weiter zum nächsten Nachfolger und zähle nen Zähler immer um 1 hoch, bis der Null Pointer kommt.
Da dies ja über Generics läuft, kann ich dort nicht einfach t.getnachfolger() machen...

btw: Die Methoden müssen nach Aufgabe alle implementiert (überschrieben) werden.
Ich darf in dieser Aufgabe keine Collection oder Arrays verwenden.

Ich hoffe ihr versteht iwie wo mein Problem liegt :)
 
Zuletzt bearbeitet:
Deine Idee für size() ist völlig korrekt. Aber dein Problem mit t.getnachfolger() verstehe ich nicht, aber Generics sind ja auch neu für dich.

Hier mal beispielhaft die size() Methode

Java:
T tmp = this.start;
int counter = 0;

while(tmp != null) {
    tmp = tmp.getNachfolger();
    counter++;
}

return counter;


Ich würde deine "VerketteteListe" Klasse noch etwas ändern. Aktuell hat diese ja von Beginn an zwei Elemente. Ich würde Sie am Anfang leer lassen (start und ende auf null).


Edit: Üblicherweise brauchst du in der size() Methode gar nichts zu programmieren, sondern du zählst in add(), remove() und clear() einfach die Anzahl mit.
 
Danke, für die Antwort, ich schau mal mit deim Code das ich die Syntax für die andren schaff.
Falls noch fragen aufkommen editier ichs rein.
Die Size muss rein, da die durch das extends als abstact von Collection kommt.

Edit:: Kann es sein, das ich bei jeder Methode eigentlich nur Start setze und dann so mit einer while schleife durchgehe? also z.B. bei add dann genau das gleiche, bis der pointer null sagt, und dann das element nehmen, was den nullpointer wirft, und nachfolger setzen, richtig?


Edit2:: hier schon das erste problem:
Code:
	public boolean add(T element)
	{
		ListenElement<T> elem = this.start;
		 
		while(elem != null) 
		{
		    elem = elem.getNachfolger();
		}
		elem.setNachfolger(element);
		element.setNachfolger(null);
		 
		return true;
	}

Die Nachfolger sind ungültig, da der Typ nicht stimmen würde ...
Ist wohl alles bischen anders mit den Generics ^^

Ich finds eh sinnlos die VerketteteListe mit <T> zu machen wenn ja eh ListElement<T> daa rein soll ... naja ...
 
Zuletzt bearbeitet:
Dass du die Methode "size()" brauchst kann ja sein, aber das heißt nicht, dass du nicht intern die Größe mit zählen kannst und in der Methode nur "return this.size" schreibst.


Der Nachfolger muss vom Typ ListElement<T> sein und nicht vom Typ T.

Java:
//falsch
elem.setNachfolger(element);

//richtig
elem.setNachfolger(new ListenElement<T>(element));
 
ok, also muss ich ganz genau aufpassen dabei, hab das einfach übersehen bzw nicht gemerkt was ich ändern muss. ok hat alles ganz gut geklappt bis jetz, hab nur grad gemerkt das ich bei add etc auch noch das objekt als nachfolger vom vorgänger setzen muss ... hach is das ein wirr warr ^^
 
Ja, hab schon viel gemacht, nur Java nie wirklich ^^ hab vorher 4 Jahre c und c++ programmiert aber jetzt durchs Studium muss ich Java.
Und Generics, wie ich jetzt gelesen habe gibt es zwar in C++, sind mir aber nie unter die Augen gekommen ^^




Hab jetzt alle Methoden fertig, kann aber leider nix testen, in der add is noch ein Fehler ...
Code:
	public boolean add(T element)
	{
		ListenElement<T> elementInList = this.start;
		 
		while(elementInList != null) 
		{
			elementInList = elementInList.getNachfolger();
		}
		ListenElement<T> dranhängen = new ListenElement<T>(element);
		elementInList.setNachfolger(dranhängen);
		dranhängen.setVorgänger(elementInList);
		dranhängen.setNachfolger(null);
		 
		return true;
	}

elementInList.setNachfolger(dranhängen); -> Can only be null at this location


komischerweise hab ich das hier nicht:
Code:
	public void add(int index, T element)
	{
		ListenElement<T> elementInList = this.start;
		 
		for(int i=0;i<index;i++)
		{
			elementInList = elementInList.getNachfolger();
		}
		ListenElement<T> dranhängen = new ListenElement<T>(element);
		elementInList.setNachfolger(dranhängen);
		dranhängen.setVorgänger(elementInList);
		dranhängen.setNachfolger(null);
	}
wobei dies am ende trotzdem ne NullPointerException schmeißt

btw: bei start und ende im konstruktor steht jetz nurnoch wie du vorgeschlagen hast
start=null;
ende=null;

sind aber halt in der klasse als private ListenElement<T> deklariert

Kanns du mir vllt auch verraten wieso die abstrackte Methode add(T) bool zurückgibt?
könnte mir höchsten vorstellen das mir try zu machen und true zurück wenns geklappt hat, aber wieso hat add(index,T) dann nur void?
Scheins dich ja gut auszukennen :)
 
Zuletzt bearbeitet:
Naja, wenn du ein Element an Stelle 10 einfügen willst, aber nur 5 Elemente in der Liste sind, läuft die Schleife in die NULL rein. Deshalb solltest du die Zahl der Elemente mitzählen und darauf prüfen.

Java:
public void add(int index, T element) {
    if(index > this.numElements) {
        throw new ArrayIndexOutOfBoundsException("You can't add an Element add position " + index);
    }

    //Dein Code
}
 
ja, sowas kenn ich ja, meine for schleife läuft doch aber über den index, worauf ich in der main selbs noch bestimme wos geaddet wird. und v1.add(0,s1); gibt mir schon ne nulltpointerexception (s1 is ein objekt, v1 die liste).
Und die boolean add(obj) geht ja ans ende und will dranhängen.

ich glaube ich hab den fehler gefunden.
start ist ja null
elementinliste ist start
elementinliste läuft durch
elementinliste wird letztes element bzw element am index
elementinliste.addnachfolger(obj)

da es mal null war kann es die methoden nicht anwenden, weil nie eine instanz erstellt wurde.
hier sollte ich die methoden von ListElement<T> dann static machen, oder?
Oder bin ich jetzt komplett auf nem falschen dampfer? ^^
habe meine ich in der letzten vorlesung nachmal den satz gehört, das static da ist um ne methode ohne gebildete instanz aufzurufen.
hab nie gerafft wofür static ist habs nie gebraucht aber das war doch dafür um methoden ohne instanz zu nutzen richtig? ^^
 
Zuletzt bearbeitet:
static hilft dir da nichts. Was du machen muss ist einfach eine Sonderbehandlung für den Fall, das start/nde == null ist.

Java:
public void add(int index, T element) {
    //Index Prüfung


    //Sonderfall bei leerer Liste
    if(this.start == null) {
        this.start = this.ende = new ListenElement<T>(element);
        return;
    }

    //Schleifen Kram
}
 
Zurück