ArrayList.add() überschreibt vorhandene Einträge.

KuShi

Mitglied
Hallo.
Ich versuche, Eine Textdatei zeilenweise einzulesen und diese Zeilen nach verarbeitung in einer ArrayList zu speichern. Hier mal die entsprechenden Code-Blöcke:

Einlesen aus Textdatei (Code-Schnipsel)
Java:
[List<IRWord>] sentence = new ArrayList<IRWord>();
					
					while ((line = readLine(in)) != null && !line.matches("</header>")) {
						while ((line = readLine(in)) != null && !line.matches("")) {
							sentence.add(processLine(line));
						}
					}

Hier die verwendete Methode processLine():
Java:
private IRWord processLine(String line) {
		IRWord word = new IRWord(line.split("\t"));

		return word;
	}

Jedes Mal, wenn ich ein neues Element (IRWord) in der ArrayList (sentence) speichere, werden die alten Elemente überschrieben. Ich weiß, dass man jedes Mal eine Neue Instanz der Elemente erstellen muss, bevor man diese in einer Liste speichert, aber ich dachte, das hätte ich in der Methode getan.
Könnt ihr mir bitte helfen, dieses Problem zu lösen, ich stehe irgendwie auf dem Schlauch.
 
S

SlaterB

Gast
in welcher Weise zeigt sich 'überschrieben', was genau prüfst du?
ist die Anzahl der Elemente in der Liste ok?
alles dieselben Objekte können es anscheinend nicht sein,
aber wenn statische Variablen im Spiel sind, wirken vielleicht alle Objekte gleich?

Details und Infos, immer könnte es mehr sein,
idealerweise sowieso vollständige Testprogramme posten, auf Datei ist dabei vielleicht verzichten,
einfach nur
> sentence.add(processLine("a"));
> sentence.add(processLine("b"));
> sentence.add(processLine("c"));
müsste doch auch eine Aussage haben
 

Korashen

Mitglied
Ich kann es leider gerade nicht nachstellen, aber splitte mal die Zeile 5 in zwei Zeilen:
Java:
IRWord irWord = processLine(line);
sentence.add(irWord);

Sollet das nicht helfen, lass die Zeilen so wie sie sind und debugge es mal:
Setze einen Breakpoint bei "sentence.add(irWord);"
Merke dir mal die Objekt-ID von "irWord".
Ist es immer die gleiche ID, dann ist es immer das gleiche Objekt, heißt, dein Array mag zwar mehrere Einträge haben, die verweißen aber alle auf das gleiche Objekt.

Eigentlich solltest du eine neue Instantz des "word" Objekts in der Methode "processLine" bekommen, da die Variable ja nur im Methoden-Fokus besteht.

Sonst, versuch mal, die Methode "processLine" zu verkürzen auf:
Java:
private IRWord processLine(String line) {
        return new IRWord(line.split("\t"));
    }
 

jstei001

Aktives Mitglied
Woher weißt du denn das die vorhanden Elemente überschrieben werden? Ist am Ende nur ein Element in dem Array?

wegen den Eckigen Klammern müsste dir der Compiler eigentlich um die ohren fliegen. Nach welchen kriterien willst du die Zeilen denn verarbeiten?
 
N

nillehammer

Gast
Die add-Methode einer Liste added wirklich. D.h. das Element wird an das Ende der Liste geschrieben. Der Liste ist es auch egal, ob evtl. schon so ein Element vorhanden ist (egal, ob gleich oder sogar identisch).

Die Frage ist jetzt, wie der Effekt, von dem Du denkst es sei "Überschreiben" wirklich zustande kommt. Anhand der vorhandenen Informationen kann man da nur raten. Weist Du der Variablen
Code:
sentence
evtl. mehrfach einen Wert zu? Überschreibst Du also evtl. die komplette Liste?

Auch Dein verschachteltes while-Schleifenkonstrukt scheint mir fehleranfällig. Trenne die Bedingung für das Lesen aus dem Reader (
Code:
line!=null
) von den Bedingungen, die fachlich die weitere Verarbeitung steuern (
Code:
line.matches("</header>"))/line.matches(""))
)

Und noch zwei Performance-Tipps:
  • Code:
    !line.matches("</header>"))
    Führt dazu, dass das Pattern, gegen das gematcht wird, jedes Mal neu kompiliert wird. Benutze besser
    Java:
    private static final Pattern HEADER_PATTERN = Pattern.compile("</header>");
    ...
    HEADER_PATTERN.matcher(line).matches();
  • Code:
    line.matches("")
    , ein regex-Matching, um rauszufinden, ob ein String leer ist, ist Overkill. Da doch lieber
    Code:
    isEmpty()
    oder
    Code:
    length() == 0
 
Zuletzt bearbeitet von einem Moderator:

KuShi

Mitglied
Danke für die flotten Antworten.

Ich verstehe die eckigen Klammern um die Liste nicht. Lass die mal weg

Die eckigen Klammern habe ich in das Script eingefügt, da dies nur ein Ausschnitt ist und im eigentlichen Programm steht an dieser Stelle nichts. Die Variable wird an anderer Stelle deklariert.

in welcher Weise zeigt sich 'überschrieben', was genau prüfst du?
ist die Anzahl der Elemente in der Liste ok?

In der Liste speichere ich Instanzen von einer Klasse IRWord, in der ich Attribute speichere, die ich aus der eingelesenen Textdatei-Zeile herauslese.
Geprüft werden die Instanzen durch eine einfache FOR-Schleife, die wie folgt aussieht (erweitertes Script)

Java:
					sentence = new ArrayList<IRWord>();
					
					while ((line = readLine(in)) != null && !line.matches("</header>")) {
						while ((line = readLine(in)) != null && !line.matches("")) {
							irWord = processLine(line);
							sentence.add(irWord);
						}
						
						String sentenceString = "";
						for (int i=0; i<sentence.size(); i++) {
							sentenceString += sentence.get(i).getWord() + " ";
						}
						log(sentenceString, "file");
						
						header.add(sentence);
					}
				}

Ich kann es leider gerade nicht nachstellen, aber splitte mal die Zeile 5 in zwei Zeilen:
Java:
IRWord irWord = processLine(line);
sentence.add(irWord);

Habe ich versucht (s.o.), funktioniert aber leider nicht.

Sollet das nicht helfen, lass die Zeilen so wie sie sind und debugge es mal:
Setze einen Breakpoint bei "sentence.add(irWord);"
Merke dir mal die Objekt-ID von "irWord".
Ist es immer die gleiche ID, dann ist es immer das gleiche Objekt, heißt, dein Array mag zwar mehrere Einträge haben, die verweißen aber alle auf das gleiche Objekt.

Habe ich gemacht.
Die Variable irWord hat immer eine andere ID

Sonst, versuch mal, die Methode "processLine" zu verkürzen auf:
Java:
private IRWord processLine(String line) {
        return new IRWord(line.split("\t"));
    }

Funktioniert leider auch nicht :(

Wenn ich das Script folgendermaßen schreibe:

Java:
					String sentenceString = "";
					sentence = new ArrayList<IRWord>();
					
					while ((line = readLine(in)) != null && !line.matches("</header>")) {
						while ((line = readLine(in)) != null && !line.matches("")) {
							irWord = processLine(line);
							sentence.add(irWord);
							
							sentenceString += irWord.getWord() + " ";
						}
						log(sentenceString, "file");
						
						sentenceString = "";
						for (int i=0; i<sentence.size(); i++) {
							sentenceString += sentence.get(i).getWord() + " ";
						}
						log(sentenceString, "file");
						
						header.add(sentence);
					}

bekomme ich folgende Ausgabe:

wechselt zu Arsenal , Frankfurt holt Inui
Inui Inui Inui Inui Inui Inui Inui

D.h. die erste Zeile ist korrekt, die zweite nicht

--------- edit ---------

Die add-Methode einer Liste added wirklich. D.h. das Element wird an das Ende der Liste geschrieben. Der Liste ist es auch egal, ob evtl. schon so ein Element vorhanden ist (egal, ob gleich oder sogar identisch).

Die Frage ist jetzt, wie der Effekt, von dem Du denkst es sei "Überschreiben" wirklich zustande kommt. Anhand der vorhandenen Informationen kann man da nur raten. Weist Du der Variablen
Code:
sentence
evtl. mehrfach einen Wert zu? Überschreibst Du also evtl. die komplette Liste?

Auch Dein verschachteltes while-Schleifenkonstrukt scheint mir fehleranfällig. Trenne die Bedingung für das Lesen aus dem Reader (
Code:
line!=null
) von den Bedingungen, die fachlich die weitere Verarbeitung steuern (
Code:
line.matches("</header>"))/line.matches(""))
)

Und noch zwei Performance-Tipps:
  • Code:
    !line.matches("</header>"))
    Führt dazu, dass das Pattern, gegen das gematcht wird, jedes Mal neu kompiliert wird. Benutze besser
    Java:
    private static final Pattern HEADER_PATTERN = Pattern.compile("</header>");
    ...
    HEADER_PATTERN.matcher(line).matches();
  • Code:
    line.matches("")
    , ein regex-Matching, um rauszufinden, ob ein String leer ist, ist Overkill. Da doch lieber
    Code:
    isEmpty()
    oder
    Code:
    length() == 0

Danke für die Tipps, ich werde diese beherzigen und meinen Code anpassen.
Interessant: Wenn ich folgenden Code einbaue:

Java:
							irWord = processLine(line);
							sentence.add(irWord);
							
							sentenceString = "";
							for (int i=0; i<sentence.size(); i++) {
								sentenceString += sentence.get(i).getWord() + " ";
							}
							log(sentenceString, "file");

bekomme ich folgende Ausgabe:

wechselt
zu zu
Arsenal Arsenal Arsenal
, , , ,
Frankfurt Frankfurt Frankfurt Frankfurt Frankfurt
holt holt holt holt holt holt
Inui Inui Inui Inui Inui Inui Inui

werde mir das nochmal ansehen.
 
Zuletzt bearbeitet:

KuShi

Mitglied
du hast IRWord immer noch nicht gepostet,
es ist für die gesamte Welt und sogar Marsianer unklar, was getWord() liefert,
kann auch von einem Zufallsgenerator abhängen ohne Code..

Sry. Hier die komplette Klasse:

Java:
public class IRWord {
	// global variables
	private static String word = null;
	private static String lemma = null;
	private static String wordForm = null;
	private static String pos = null;
	private static String label = null;
	private static int knot;
	private static String[] morphology = null;
	
	public IRWord(String[] wordArray) {
		word = wordArray[1];
		lemma = wordArray[2];
		wordForm = wordArray[3];
		pos = wordArray[4];
		morphology = wordArray[5].split("|");
		knot = Integer.parseInt(wordArray[6]);
		label = wordArray[7];
	}
	
	public String getWord() {
		return word;
	}
}
 

njans

Top Contributor
Da alle Attribute statisch sind, wird dies immer überschrieben, wenn ein neues Objekt erzeugt wird. Der Sinn von static ist eben, dass es nur einmal existiert. Du speicherst so immer nur das neuste Objekt.
Du musst die Attribute eben nicht static machen.
 
N

nillehammer

Gast
Danke für die Tipps, ich werde diese beherzigen und meinen Code anpassen.
Und noch was: Die zweifach verschachtelte while-Schleife mit mehrfachem read ist schon schwer durchschaubar. Jetzt kommt darin noch eine for-Schleife! Über Ausgaben in merkwürdiger Reihenfolge brauchst Du Dich da nicht zu wundern. Refactor das unbedingt. Überlege, ob Du wirklich alle Schleifen brauchst. Falls ja, lager sie in eigene Methoden mit geeigneten Übergabeparametern/Return-Values aus. Damit bist Du dann auch in der Lage, jede Methode einzeln zu testen und findest den Fehler schneller.
 

KuShi

Mitglied
Da alle Attribute statisch sind, wird dies immer überschrieben, wenn ein neues Objekt erzeugt wird. Der Sinn von static ist eben, dass es nur einmal existiert. Du speicherst so immer nur das neuste Objekt.
Du musst die Attribute eben nicht static machen.

Danke, das war die Lösung.

Danke euch allen für eure Hilfe.

--------- edit ---------

Und noch was: Die zweifach verschachtelte while-Schleife mit mehrfachem read ist schon schwer durchschaubar. Jetzt kommt darin noch eine for-Schleife! Über Ausgaben in merkwürdiger Reihenfolge brauchst Du Dich da nicht zu wundern. Refactor das unbedingt. Überlege, ob Du wirklich alle Schleifen brauchst. Falls ja, lager sie in eigene Methoden mit geeigneten Übergabeparametern/Return-Values aus. Damit bist Du dann auch in der Lage, jede Methode einzeln zu testen und findest den Fehler schneller.

Diese For-Schleifen sind ja auch nur zum Test. Werde das noch umschreiben. Danke aber trotzdem für den Hinweis.
 

Korashen

Mitglied
Ah ja, mit dem Code zur IRWord-Klasse ist es leicht nach zu vollziehen, wieso du immer die gleichen Werte bekommst ;-)

Und die Moral von der Geschicht, vergiss die Klassen nicht :D

Na, mehr oder weniger ;-)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
P Schiebefix - ArrayList überschreibt Daten Java Basics - Anfänger-Themen 3
C ArrayList - überschreibt Elemente Java Basics - Anfänger-Themen 7
P ArrayList aus eigener Klasse "überschreibt" Werte nicht Java Basics - Anfänger-Themen 4
H Java- ArrayList überschreibt Werte eigenständig! Java Basics - Anfänger-Themen 4
krgewb ArrayList allgemein halten Java Basics - Anfänger-Themen 6
M Ausgabe einer ArrayList ensteht nur als Hashcode, nicht als Objekt Java Basics - Anfänger-Themen 16
S Java: Wie sortiere ich eine ArrayList benutzerdefinierter Objekte nach einem bestimmten Attribut? Java Basics - Anfänger-Themen 2
J ArrayList in 2D-Array konvertieren. Java Basics - Anfänger-Themen 48
E Arrays in einer ArrayList miteinander vergleichen Java Basics - Anfänger-Themen 12
String in ArrayList umwandeln Java Basics - Anfänger-Themen 1
F Arraylist<String>Ein Wort pro Zeile Java Basics - Anfänger-Themen 6
J ArrayList vergleichen im spiel Mastermind Java Basics - Anfänger-Themen 2
Mugetsu35 ArrayList Update ohne Index Java Basics - Anfänger-Themen 6
W Objekte einer ArrayList in txt-datei schreiben mit Paths? Java Basics - Anfänger-Themen 2
Z Java ArrayList speichert falsche Daten ab bzw. gibt falsche Daten aus? Java Basics - Anfänger-Themen 42
W if-Abfrage bei ArrayList-Methodenaufrufen - Wie löse ich das? Java Basics - Anfänger-Themen 6
W ArrayList und toString Java Basics - Anfänger-Themen 17
volcanos Addition -> List<Integer> mit Arrays.asList() versus List<Integer>ArrayList<>() Java Basics - Anfänger-Themen 14
ArrayList mit unbekannter Menge an Arrays die Arrays vergleichen Java Basics - Anfänger-Themen 9
M 2d ArrayList durchgehen Java Basics - Anfänger-Themen 2
Blkckroll45 Arraylist Java Basics - Anfänger-Themen 6
H Interface Wieso "List<String> list = new ArrayList<>[…]" Java Basics - Anfänger-Themen 4
berserkerdq2 Geht collections.sort bei allen? Linkedhashset, ArrayList, HashSet etc. Java Basics - Anfänger-Themen 4
R Methoden Werte einer ArrayList als Parameter übergeben. Java Basics - Anfänger-Themen 4
L Dauerhaftes Speichern einer Eingabe bei einer ArrayList Java Basics - Anfänger-Themen 26
D Arraylist mit Komplexen Datentyp Java Basics - Anfänger-Themen 3
H Kompliziertes Sortieren einer ArrayList mit Objekten(Sortieren nach X und Y) Java Basics - Anfänger-Themen 11
T Permanentes speichern von Objekten in einer ArrayList Java Basics - Anfänger-Themen 6
volcanos List & ArrayList nach Familiennamen abfragen Java Basics - Anfänger-Themen 57
M static ArrayList in non-static Java Basics - Anfänger-Themen 12
berserkerdq2 Ich gebe eine ArrayList als List zurück per MEthode, wie kann ich nun aber die ArrayList speichern? Java Basics - Anfänger-Themen 46
M ArrayList<TreeNode<T>> fortlaufende Nummerierung der Elemente Java Basics - Anfänger-Themen 5
B Bungeecord | ProxiedPlayer wird nicht in ArrayList hinzugefügt Java Basics - Anfänger-Themen 1
S ArrayList Username und passwort mit JTextField eingaben abgleichen Java Basics - Anfänger-Themen 10
F Werte in einer Arraylist Zählen Java Basics - Anfänger-Themen 2
F Erste Schritte Zahlenreihe von Arraylist in 3erBlöcke sortiert in neue Arraylist Java Basics - Anfänger-Themen 2
M ArrayList mit einer Schleife befüllen Java Basics - Anfänger-Themen 2
F Methode ArrayList mit Eingabewert Java Basics - Anfänger-Themen 2
J ArrayList add methode selbst programmieren Java Basics - Anfänger-Themen 10
K Erste Schritte Wie schnell ist LinkedHashMap im Vergleich zur ArrayList, wenn alle Entries durchlaufen werden? Java Basics - Anfänger-Themen 47
thobren jtable arraylist Java Basics - Anfänger-Themen 12
N Exception beim Verwenden von Arraylist? Java Basics - Anfänger-Themen 10
Zeppi OOP ArrayList Java Basics - Anfänger-Themen 2
P ArrayList Java Basics - Anfänger-Themen 4
L ArrayList auf 4 Elemente begrenzen Java Basics - Anfänger-Themen 56
C ArrayList sortieren nach bestimmten Buchstaben in den Wörtern Java Basics - Anfänger-Themen 13
S Arraylist<Object> mit verschiedenen Objects ausgeben Java Basics - Anfänger-Themen 3
J ArrayList auf bereits vorhanden eintrag prüfen Java Basics - Anfänger-Themen 5
M For Schleife/ArrayList Java Basics - Anfänger-Themen 12
L ArrayList<String> --> double[] array Java Basics - Anfänger-Themen 18
L Längstes Element einer ArrayList ausgeben Java Basics - Anfänger-Themen 9
S Aus verschachtelter ArrayList auf einen Wert zugreifen Java Basics - Anfänger-Themen 4
L Methoden ArrayList Werte hinzufügen und löschen Java Basics - Anfänger-Themen 32
M ArrayList in GUI ausgeben Java Basics - Anfänger-Themen 1
J Nur bestimmter Typ aus der ArrayList ausgeben. Java Basics - Anfänger-Themen 9
Bademeister007 Hallo Leute ich hab eine Frage zur ArrayList Java Basics - Anfänger-Themen 8
Bademeister007 Operatoren Alle Zahlen einer ArrayList die durch 5 teilbar ist Java Basics - Anfänger-Themen 2
S Objekt aus Arraylist in andere Arraylist kopieren? Java Basics - Anfänger-Themen 2
C Sortieren einer ArrayList Java Basics - Anfänger-Themen 2
krgewb ArrayList von ArrayList Java Basics - Anfänger-Themen 2
R ArrayList Problem Java Basics - Anfänger-Themen 6
jonny_2k12 Wie kann ich eine ArrayList aus einer Klasse in eine andere übergeben? Java Basics - Anfänger-Themen 21
O Namen (mit Umlauten und ß) in einer ArrayList suchen Java Basics - Anfänger-Themen 5
N Typebound Objekte einer Arraylist hinzufügen Java Basics - Anfänger-Themen 7
R Methoden ArrayList clonen wirft exception Java Basics - Anfänger-Themen 3
S ArrayList in andere Klasse übernhemen Java Basics - Anfänger-Themen 5
M Letztes Element einer ArrayList Java Basics - Anfänger-Themen 12
B Objektverwaltung mit ArrayList in einer seperaten Klasse Java Basics - Anfänger-Themen 24
I Sortiert eine HashMap nicht gleich wie eine ArrayList? Java Basics - Anfänger-Themen 1
I ArrayList erstellen innerhalb einer Zeile? Java Basics - Anfänger-Themen 3
L Iterieren durch eine ArrayList. Integer Array wird übergeben Java Basics - Anfänger-Themen 17
V Collections ArrayList mit Comparator sortieren Java Basics - Anfänger-Themen 16
D Collections Arrays in ArrayList abspeichern Java Basics - Anfänger-Themen 6
F java.util.ArrayList Java Basics - Anfänger-Themen 3
M ArrayList - Objekt kopieren und ändern Java Basics - Anfänger-Themen 11
M Zugriff auf eine ArrayList in einer anderen Klasse Java Basics - Anfänger-Themen 4
P Arraylist zu einem Array bringen mit Verschachtelung Java Basics - Anfänger-Themen 11
N Methode mit einer Arraylist Java Basics - Anfänger-Themen 106
I ArrayList - Methode zum Speichern eines Eintrags in einer Datei Java Basics - Anfänger-Themen 17
H ArrayList Java Basics - Anfänger-Themen 7
D public ArrayList(Collection<? extends E> c); Java Basics - Anfänger-Themen 2
M JTextField in ArrayList speichern Java Basics - Anfänger-Themen 4
C ArrayList mit return zurückgeben Java Basics - Anfänger-Themen 13
K Zahlenfolge ArrayList Java Basics - Anfänger-Themen 3
C Erste Schritte Frage zur ArrayList Java Basics - Anfänger-Themen 15
I Klassen Eine ArrayList<Long>, die sich automatisch sortiert Java Basics - Anfänger-Themen 20
F Array in ArrayList ablegen Java Basics - Anfänger-Themen 3
V ArrayList Java Basics - Anfänger-Themen 1
Z Runden Arraylist Java Basics - Anfänger-Themen 9
X Frage zur einer ArrayList in einer ArrayList Java Basics - Anfänger-Themen 5
F Arraylist als Pfadausgabe Java Basics - Anfänger-Themen 10
L Daten aus ArrayList in Datenbank durchsuchen Java Basics - Anfänger-Themen 5
L Objekt aus Textdatei in ArrayList speichern Java Basics - Anfänger-Themen 4
M Problem mit ArrayList Java Basics - Anfänger-Themen 32
X Objekte einer ArrayList richtig ausgeben? Java Basics - Anfänger-Themen 8
O Hashmap, ArrayList, LinkedList Java Basics - Anfänger-Themen 7
X Problem mit Arraylist in Arraylist Java Basics - Anfänger-Themen 2
O HashMap - ArrayList Java Basics - Anfänger-Themen 29
M UML-Klassendiagramm ArrayList Java Basics - Anfänger-Themen 1
O ArrayList oberflächig durchsuchen Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben