ArrayListe delete Methode klappt nicht

dan1996

Aktives Mitglied
Hallo ich versuche grade bei meiner ArrayListe die delete Methode zu schreiben, jedoch wenn mein Array voll ist und ich ein Wert löschen will entsteht eine
ArrayIndexOutOfBoundsException, kann mir jemand dabei helfen?


*frei = mein pointer
Java:
    public AListe<T> delete(T x) {
        if (array[length()] == x) { // wenn letzter Wert == x ist, auf null setzen
            array[length()] = null;

        } else {
            for (int i = 0; i < length(); i++) {
                if (array[i] == x) { // wert im array gefunden
                    for (int j = i; j < length() - 1; j++) {
                        array[j] = array[j + 1];
                    }
                }
                break;
            }
            
        }
        frei--;
        return this;
    }
 
K

kneitzel

Gast
Also was mir auffällt: Du vergleichst Referenzen mit "==" - da solltest du equals nutzen.

Das Problem ist da aber so nicht zu erkennen für mich. Zeig einmal den ganzen Code. Was ist length(), wie ist array deklariert und initialisiert?
Also am Besten die ganze Klasse zeigen und nicht nur so kleine Ausschnitte.

Generell: Wenn Du da ein Array nutzt und das Array die Größe length() hat, dann kannst Du nicht auf array[length()] zugreifen. Der Index fängt bei 0 an, also bei 3 Elemente hast Du die Elemente 0, 1, 2 -> maximales Element ist also n-1 bei n Elementen.
 

dan1996

Aktives Mitglied
Java:
class AListe<T extends Number> {

    private int size;
    private T array[];
    private int frei = 0;

    @SuppressWarnings("unchecked")
    public AListe(int size) {
        this.size = size;
        this.array = (T[]) new Number[size];
    }

    public boolean isEmpty() {
        return frei == 0;
    }

    public AListe<T> insert(T x) { //wert am anfang einfügen
        if (isEmpty()) {
            append(x);
        } else {
            for (int i = length(); i > 0; i--) {
                array[i] = array[i - 1];
            }
            array[0] = x;
            frei++;
        }

        return this;
    }

    public AListe<T> append(T x) { //wert am Ende einfügen
        array[frei] = x;
        frei++;
        return this;
    }

    public AListe<T> delete(T x) {
        if (array[length()].equals(x)) { // wenn letzter Wert == x ist, auf null setzen
            array[length()] = null;

        } else {
            for (int i = 0; i < length(); i++) {
                if (array[i].equals(x)) { // wert im array gefunden
                    for (int j = i; j < length(); j++) {
                        array[j] = array[j + 1];
                    }
                }
                break;
            }
           
        }
        frei--;
        return this;
    }

    public T firstElement() {
        return array[0];
    }

    public int length() {
        return frei;
    }

    public int size() {
        return size;
    }
 
K

kneitzel

Gast
Also ich schaue es mir gerade an um es zu verstehen. Die Namen sind in meinen Augen schlecht gewählt ... Es ist nicht intuitiv, dass length() frei zurück gibt. "frei" wäre sowas wie "nextfreeElement" oder so...


Code:
public AListe<T> insert(T x) {
        if (isEmpty()) {
            append(x);
        } else {
            for (int i = length(); i > 0; i--) {
                array[i] = array[i - 1];
            }
            array[0] = x;
            frei++;
        }

        return this;
    }

Die isEmpty Prüfung braucht es nicht. idEmpty ist dann wahr, wenn frei == 0, damit hast du eine Schleife, die nie durchlaufen wird (i wird ja auf 0 gesetzt) und daher hast Du direkt die Aktivität von Append (dessen Return-Wert du ehh ignorierst) ==> Also auch doppelter code!

Wenn length() = frei = Nächstes freies Element:
Dann ist dein Delete Unsinn: Du prüfst, ob auf dem nächsten freien Element das gesuchte Element ist. Da müsste aber doch ehh null drin stehen... Und die "Verbesserung" mit dem equals führt jetzt zu einer NPE, weil Du auf null ein equals aufrufst. (oder sollte ich mich da jetzt irren?)

So wie bei dem insert brauchst du da auch gar keine Sonderbehandlung.
Du machst eine Schleife von 0 bis <length. So Du das Element noch nicht gefunden hast, prüfst Du nur, ob das Element da ist.
Sobald Du das Element gefunden hast:
Bist du auf dem letzten Element (size prüfen!), dann schreibst Du in das aktuelle Element null, ansonsten kopierst Du nur das nächste Element auf das aktuelle Element.

So wäre ein möglicher Code, den ich mir gerade ohne viel drüber nachzudenken überlegt habe.

Ansonsten noch:
Generell musst Du natürlich bei einem Insert prüfen, ob length() schon size() ist. Dann wäre das Array voll und du kannst nichts mehr einfügen.
 

dan1996

Aktives Mitglied
ich danke dir schonmal, die Sachen die du bemängelt hast, wie Name, isEmpty, append, length und insert standen bei mir so in den Vorlesungsfolien und ich wollte eigentlich nur noch eine delete Methode in die Klasse hinzufügen. Ja genau mit insert stimmt auch, nur dass ich das noch nicht dazu geschrieben habe
 
K

kneitzel

Gast
Wenn so Namen vorgegeben wurden, dann ist dem (leider) so. Das betrifft halt nicht die Funktionalität sondern geht halt in den Bereich Clean Code und Lesbarkeit des Codes.

Die Anmerkungen zu der Delete Methode waren verständlich? (Und das mit dem "Unsinn" nicht persönlich nehmen - das klassifiziert Dich nicht Deine Arbeit oder Person sondern lediglich den Code an der Stelle. Und das da nicht alles perfekt ist, hast Du ja auch gemerkt sonst hätte Du ja nicht die Thematik hier gepostet. Das nur am Rande, weil mir das gerade noch einmal ins Auge fiel. Blöd / Unhöflich formuliert von mir, aber ich habe mir zu wenig Zeit genommen und mit Blick auf deinem Code einfach paar Sachen runter geschrieben.)
 

dan1996

Aktives Mitglied
Alles gut gar kein Thema, bei der Stelle:
Bist du auf dem letzten Element (size prüfen!), dann schreibst Du in das aktuelle Element null
wenn ich mein Element, was ich ja löschen will, auf null schreibe, muss ich doch alle Werte danach um ein index nach links verschieben, was ja mein Problem ist.. Es funktioniert irgendwie nicht :D
 
K

kneitzel

Gast
ja, das musst Du. Aber wenn das Array voll ist, dann kommst Du irgendwann zum letzten Element.
Bei dem letzten Element kannst Du natürlich keinen Nachfolger mehr kopieren sondern statt dessen kannst Du nur noch null rein schreiben.

Also Du hast 10 Elemente. Beim 10. Element kannst Du nicht mehr versuchen, das 11. Element in das 10. Element zu schreiben. Du musst erkennen: "Ich bin am Ende angekommen" und dann das Feld einfach frei machen (null zuweisen).
 

dan1996

Aktives Mitglied
habe ich grade einen Denkfehler oder warum klappt das nicht, aber erstmal Danke für deine Hilfe
Java:
public AListe<T> delete(T x) {

        if (array[length()] == x) { // wenn letzter Wert == x ist, auf null setzen
            array[length()] = null;

        } else {

            for (int i = 0; i < length(); i++) {
                if (array[i] == x) { // wert im array gefunden

                    for (int j = i; j < length(); j++) {

                        if (j == size()) {
                            array[j] = null;
                        } else {
                            array[j] = array[j + 1];
                        }
                    }
                }
            }
        }
        frei--;
        return this;
 
K

kneitzel

Gast
Versuch es mal in der Art und Weise (ungeprüft und ggf. mit Tippfehlern)

Java:
public AListe<T> delete(T x) {
/*
        if (array[length()] == x) { // wenn letzter Wert == x ist, auf null setzen
            array[length()] = null;

        } else {
*/
            boolean gefunden = false;
            int current = 0;
            while (current < length()) {
                if (gefunden) {
                    if (current == size()-1) { // -1! Bei 10 Elementen ist das letzte die 9!
                        array[current] = null;
                    } else {
                        array[current] = array[current + 1];
                    }
                    current++;
                } else if (array[current].equals(x) {
                    gefunden = true;
                    // Wir gehen nicht weiter! Im nächsten Durchgang wird das Element überschrieben.
                } else {
                    current++;
                }
            }
//        }
        if (gefunden) frei--;
        return this;
}

Also der erste Part muss raus da der so kein Sinn gemacht hat.

Dann waren die zwei schleifen blöd, denn wenn du in der inneren bis zum Ende gelaufen bist, dann bist du danach in der äußeren auch noch weiter gelaufen. Da aber jetzt nicht immer erhöht wird habe ich keine for Schleife mehr sondern eine while Schleife.

Ein Fehler war noch die Erkennung des letzten Elements. Das letzte Element ist size() - 1 und nicht size()!

Und er reduziert frei nur, wenn er auch ein Element gefunden hat...

Dann ist der Ablauf einfach:
- Er geht in einer Schleife alle Elemente durch:
-- Hat er das Element bereits gefunden, dann nehmen wir nur noch das nächste Element oder eben null, wenn es das nicht gibt. Und gehen weiter.
-- Wenn er das Element noch nicht gefunden hat, dann prüft er das aktuelle Element. Ist es das, dann hat er es gefunden und er kann ohne weiter vor zu rücken einfach erneut den Schleifen-Körper durchlaufen womit er den ersten Punkt ansteuert.
-- Wenn er das Element noch nicht gefunden hat und das aktuelle Element nicht das gesuchte ist, dann geht er ein Element weiter.
- am Ende: Wenn das Element gefunden wurde, dann wurde ja ein Element entfernt - daher ist frei um eins zu reduzieren.

Das return this macht nicht wirklich Sinn. Ich hätte da eine void oder boolean Methode erwartet. Bei boolean könnte man gefunden zurück geben.
 

dan1996

Aktives Mitglied
ich danke dir, es funktioniert alles einwandfrei, danke!!!
Das Return this wollten die in den Vorlesungsfolien haben, habe auch keine Ahnung warum
 
K

kneitzel

Gast
Naja ...damit kann man so Aufrufe aneinander reihen. Wenn man immer die eigentliche Instanz hat, dann schreibt man sowas wie:
Code:
meineListe
  .insert(1)
  .insert(2)
  .delete(3)
  .print()
  .delete(2)
  .insert(14);

Das ist recht bekannt bei dem "Builder Pattern".Um komplexe Konstruktoren zu vermeiden wird da auf eine Builder klasse zurück gegriffen. Da macht es dann auch tatsächlich Sinn:
Code:
Adresse adresse = Adresse.builder()
                    .name("Anton Maier")
                    .strasse("Musterstrasse 17")
                    .plz("12345")
                    .ort("Musterhausen")
                    .land("Musterland")
                    .build();

Außerhalb von Buildern ist das aber zumindest unüblich.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
N Arrayliste in eine Datei speichern Allgemeine Java-Themen 4
H ArrayListe in CSV Datei speichern Allgemeine Java-Themen 6
Y ArrayListe eingegebenen index entfernen Allgemeine Java-Themen 1
kodela Arrayliste mit Arrayliste realisieren Allgemeine Java-Themen 14
GreenTeaYT Verstehe nicht ganz das Observer Pattern in einer Arrayliste? Allgemeine Java-Themen 3
M ArrayListe & Mac Allgemeine Java-Themen 1
S Erste Schritte Arrayliste alphabetisch sortieren mit Eingabe Allgemeine Java-Themen 9
T ObjectInputStream - Arrayliste, die unbekannte Objekte enthält Allgemeine Java-Themen 9
S Element aus ArrayListe löschen --> Thread hängt sich auf Allgemeine Java-Themen 2
A ArrayListe :Doppelte entfernen -> keine Referenzen Allgemeine Java-Themen 26
M Delete bei sortierter LinkedList Allgemeine Java-Themen 5
R Delete files before creating new from temp using Java file method Allgemeine Java-Themen 1
J ftp - delete file ohne appache Allgemeine Java-Themen 8
C file.delete() funktioniert bei zweiten aufruf nicht mehr Allgemeine Java-Themen 3
P REST- Services GET/PUT/POST/DELETE Allgemeine Java-Themen 6
M Threads synchroner Zugriff (add/delete/read) auf eine Liste Allgemeine Java-Themen 6
L Class Files , Methode .delete() Allgemeine Java-Themen 13
F HTTP REST und DELETE Allgemeine Java-Themen 9
G sorted BinTree & delete Methode Allgemeine Java-Themen 2
H File delete löscht manche dateien nicht Allgemeine Java-Themen 2
A Problem mit StringBuilder delete - find den Fehler nicht Allgemeine Java-Themen 9
R File#delete funktioniert manchmal nicht Allgemeine Java-Themen 2
M file.delete() braucht ewig Allgemeine Java-Themen 3
S aFile.delete() liefert false - Gründe ? Allgemeine Java-Themen 2
W Hilfe bei Methode Allgemeine Java-Themen 14
Ü Methoden Arrays vergleichen - Methode Allgemeine Java-Themen 1
Simon16 compareTo Methode überschreiben Allgemeine Java-Themen 4
TheSkyRider Methode über DataInputStream "auslösen" Allgemeine Java-Themen 6
M CrudRepository save Methode mocken Allgemeine Java-Themen 6
thor_norsk toString() - Methode Allgemeine Java-Themen 6
A Clean Code: Variable vs. Methode Allgemeine Java-Themen 8
Encera Zweite Main-Methode zuschalten Allgemeine Java-Themen 18
M Optimierung einer Methode (byte-Geraffel) Allgemeine Java-Themen 2
I Hibernate Envers - Aufruf der Methode zum Speichern selbst ausführen oder managen? Allgemeine Java-Themen 0
N rekursion mehrfach eine Methode Öffnen Allgemeine Java-Themen 4
berserkerdq2 Wenn ich eine Methode nur jede 50ms ausführen will, wie mach ich das? Allgemeine Java-Themen 4
berserkerdq2 run-methode eines Threads so programmieren, dass 30x die Sekunde etwas ausgeführt wird. Allgemeine Java-Themen 44
N Schnellste Methode, ein Array durchzugehen? Allgemeine Java-Themen 9
E Methoden abstract static Methode Allgemeine Java-Themen 8
E Eine Methode einer extendeten Klasse deakitivieren Allgemeine Java-Themen 12
F Getter Methode aufrufen funktioniert nicht Allgemeine Java-Themen 1
B In Java Methode mit generic input und output basteln? Allgemeine Java-Themen 4
goldmensch Datentypen Welche Methode hat die bessere Performance? Allgemeine Java-Themen 12
R Lambda Expression in einer Methode execute() aufrufen (execute() ist eine Methode aus dem funktionalen Interface Command) Allgemeine Java-Themen 5
T C++ Methode Übersetzung in Java Allgemeine Java-Themen 3
L Erste Schritte TDD testen einer Methode mit injezierten Services? Allgemeine Java-Themen 12
R @author vor Methode (eclipse) Allgemeine Java-Themen 1
J RotSchwarzBaum: Löschen mittels insert-Methode Allgemeine Java-Themen 20
Y Java Bruttoberechnen + runden Methode Allgemeine Java-Themen 1
R Warum ist die Methode unendlich oft rekursiv? Allgemeine Java-Themen 5
R Methoden Was fehlt mir bzw. muss ich bei der Methode countHarshabNumbers ändern damit ich die Harshad Zahlen im Intervall [51, 79] zählen kann? Allgemeine Java-Themen 19
Drachenbauer Wie finde ich den Aufrufer zu einer Methode, die sich nicht in meinem Projekt befindet? Allgemeine Java-Themen 2
A Ist ein enum hier richtig? Enum toString() Methode. Allgemeine Java-Themen 1
Scream_ilias brute force methode verbessern? Allgemeine Java-Themen 6
Scream_ilias passwort meines pc per brute force methode knacken Allgemeine Java-Themen 4
S static methode im Interface Allgemeine Java-Themen 1
M Konstruktor einer Methode Allgemeine Java-Themen 35
A HashMap Methode "get()"-Problem Allgemeine Java-Themen 28
E Hat der Compiler einen Fehler oder warumbeendet return nicht eine Methode ? Allgemeine Java-Themen 7
T Sinn einer toString Methode Allgemeine Java-Themen 3
T Split() Methode funktioniert nicht?! Allgemeine Java-Themen 11
L Methoden Über Reflections eine Methode mit aufrufen Allgemeine Java-Themen 3
S Kann ich eine Methode schreiben die alle Arten von funktionalen Interfaces akzeptiert..? Allgemeine Java-Themen 21
L ToString-Methode Allgemeine Java-Themen 6
X Datentypen NPE in längerer Methode Allgemeine Java-Themen 12
I Methoden Generics-Methode Allgemeine Java-Themen 3
H Strategy Pattern - changeColor() Methode - input rgd oder hex einlesen Allgemeine Java-Themen 1
T statische Variable und nicht-statische Methode Allgemeine Java-Themen 2
B Aufruf der Methode ergibt eine Exception Allgemeine Java-Themen 13
M Wie kann ich ein int[] Array in einer Methode benutzen? Allgemeine Java-Themen 6
M Wie kann man eine void Methode mit Variablen von zwei verschiedenen Objekten ausführen? Allgemeine Java-Themen 15
F Was ist der Dateityp meines Parameters für die Main Methode. Allgemeine Java-Themen 6
F Variablen Palindromzahl (Probleme mit Methode) Allgemeine Java-Themen 9
B APi methode kurz anhalten Allgemeine Java-Themen 8
P Methode aus anderem Paket aufrufen Allgemeine Java-Themen 1
K ursprüngliche ArrayList ändert sich bei Übergabe in Methode Allgemeine Java-Themen 18
R Rekursive Methode Allgemeine Java-Themen 8
ReinerCoder Methode einer Klasse meldet Fehler "misplaced construct(s)" Allgemeine Java-Themen 13
R Wo ist mein Fehler in der Methode DRINGEND Allgemeine Java-Themen 9
I Collection - contains-Methode überschreiben (anonyme innere Klasse) Allgemeine Java-Themen 4
E RMI NULL-Pointer-Exeception wenn der RMI-Proxy eine Methode deligiert Allgemeine Java-Themen 2
S Methoden Liste soll Methode aus innerer Klasse aufrufen Allgemeine Java-Themen 4
M Methoden Generische Methode für ArrayList Allgemeine Java-Themen 7
D HTTP Aufruf einer Methode aus einem Servlet heraus Allgemeine Java-Themen 0
C Threads Methode verhält sich merkwürdig Allgemeine Java-Themen 18
R rekursive und iterative Methode Allgemeine Java-Themen 3
P Methoden Anwendung der allMatch()-Methode Allgemeine Java-Themen 5
G Programm, das nach abgearbeiteter main Methode weiterläuft Allgemeine Java-Themen 72
D Methoden Methode zum Steinschnitt Allgemeine Java-Themen 2
U OOP Warum kann ich aus meiner Methode keinen String auslesen Allgemeine Java-Themen 4
T Methoden Methode zum durchsuchen einer ArrayList Allgemeine Java-Themen 8
D Returnwert aus einer Methode gerundet ausgeben lassen Allgemeine Java-Themen 2
S equals-Methode bestimmer Klassen abfangen Allgemeine Java-Themen 2
H Methoden Methode 'updateItem' der Klasse 'TreeCell' Allgemeine Java-Themen 3
snipesss Methode greift nicht auf JTextPanel zu Allgemeine Java-Themen 3
R Methode in Methode voraussetzen Allgemeine Java-Themen 8
S Überschriebene Methode der Oberklasse der Oberklasse aufrufen. Allgemeine Java-Themen 5
D Methode dynamisch aufrufen Allgemeine Java-Themen 2
Sogomn Methode als Parameter? Allgemeine Java-Themen 3
M Eigene forEach()-Methode funktioniert nicht. Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben