Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
wie der Titel schon sagt, will ich während der Laufzeit meinem ListView Strings hinzufügen. Mir ist natürlich bewusst, dass das während der Iteration nicht so einfach funktioniert, da es ja sonst einen Concurrent Modification Exception erhalte.
Es geht jetzt tatsächlich wirklich um ein Codebeispiel von der Syntax, damit ich in einer Liste wo sich bereits Strings befinden, weitere hinzufüge. Wenn ich in Google nach ListViews suche, tauchen immer nur Android Themen auf.
Ich habe weder Ahnung, was das mit der Fragestellung (bzgl JavaFX-ListViews) zu tun hat, noch was das überhaupt soll?
Das ganze kannst du auch einfach schreiben als:
Java:
while (true) { //Edit, muss natürlich wine Endlosschleife sein for (int i = 0; i < count; i++) {
stringCollection.add(irgendeinString);
myContent.refresh();
}
Dann passiert das gleiche, aber deutlich offensichtlicher und ohne versteckte Fallen wie ConcurrentModificationException...
Ich habe weder Ahnung, was das mit der Fragestellung (bzgl JavaFX-ListViews) zu tun hat, noch was das überhaupt soll?
Das ganze kannst du auch einfach schreiben als:
Java:
while (true) { //Edit, muss natürlich wine Endlosschleife sein for (int i = 0; i < count; i++) {
stringCollection.add(irgendeinString);
myContent.refresh();
}
Dann passiert das gleiche, aber deutlich offensichtlicher und ohne versteckte Fallen wie ConcurrentModificationException...
Ich weiß dass ich manchmal etwas chaotisch schreibe. Ich lerne. Und da passieren Fehler.
Du kommst mir oftmals hochnäsig vor. Tut mir leid falls ich mich irre. Ich habe nämlich das Gefühl, dass du denkst, dass dein Gesprächspartner immer den gleichen Wissensstand hat wie du. Dem ist aber nicht so.
Ich schätze deine Antworten und dein Wissen und will dich nicht beleidigen, aber so kommt es leider oftmals rüber.
Ich will damit keines Falls Flames lostreten. Du musst auch nicht darauf antworten.
Dein letzter Code fügt einfach nur in einer (komplizierten) Endlosschleife das immer gleiche Element einer Liste hinzu.
Kann gut sein, dass wir aneinander vorbei geredet haben - allerdings glaube ich auch nicht, dass deine Lösung wirklich eine Lösung für irgendein Problem ist, Sollte das bei dir wirklich so funktionieren, ist da irgendwo anders noch ein Problem.
gestern war ich in der Tat etwas voreilig. Ich hatte mit Alt + Tab kurz das Fenster gewechselt und habe nur gesehen, dass die Exception weg war und dabei nicht bemerkt, dass sich die App aufgehängt hat.
Da ist dies eingetroffen, was Mr. Brown beschrieben hat. Und zwar eine Endlosschleife, worauf die App nicht mehr reagierte.
Die Sache sagt mir nun zwei Dinge:
1. Ich habe zwar verstanden warum man etwas iterieren muss, verstehe aber nicht, was da genau im Hintergrund passiert.
2. Verstehe ich nicht, warum mein Code - der ja falsch ist, eine Endlosschleife produziert. Was aber mit Punkt 1 zusammenhängt.
Ich sage jetzt erstmal was ich vorhabe. Ich hoffe ihr habt noch Lust
Also:
Ich sag es gleich im Vorfeld: Es gibt bestimmt einfache Methoden sowas zu machen, aber das war meine Idee und wollte es so umsetzten. Für Vorschläge bin ich aber dennoch offen
Es handelt sich eigentlich um ein schlichtes Inhaltsverzeichnis, dass alphabetisch geordnet sein soll. Darin sollen dann Namen gespeichert werden. Als optisches Schmankerl wollte ich aber dass sobald ein neuer Buchstabe beginnt, dieses mit beispielsweise "A" abgegrenzt ist. Ich habe das Alphabet im Vorfeld dieser Liste hinzugefügt.
Für Trockenübungen habe ich einfach ein Textfeld, ein Button und ein ListView. Dann habe ich eine Methode geschrieben, die erkennen soll mit welchen Buchstabe ein Name beginnt und diesen dann an der richtigen Stelle in der Liste einfügen soll.
Die Methode sieht bis jetzt so aus.
Code:
private void addDataInContentList() {
String userEntry = searchAusgabeTxtField.getText();
userEntry.trim();
userEntry.substring(0, 1).toUpperCase();
String firstChar = "" + userEntry.substring(0, 1);
for (String s : stringCollection) {
if (s.equals(userEntry)) {
return;
}
}
for(String s : stringCollection) {
if (s.equals(firstChar)) {
int indexTargetChar = stringCollection.indexOf(s);
stringCollection.add(indexTargetChar + 1, userEntry);
myContent.refresh();
}
}
}
Ich muss nun gestehen dass während ich diese Zeilen schreibe ich meinen Code so ausgeführt habe und plötzlich kommt keine ConcurrentModificationException mehr. Ich bin verwirrt.
Diese Methode, so wie sie oben steht, hatte gestern die Exception geworfen und war der Grund, warum ich hier gepostet habe.
Äh. ja. Ich weiß nicht, was ich jetzt sagen soll *g*
Vielleicht kann mir trotzdem jemand erklären, was da genau beim Iterieren passiert.
2. Verstehe ich nicht, warum mein Code - der ja falsch ist, eine Endlosschleife produziert. Was aber mit Punkt 1 zusammenhängt.
[...]
Vielleicht kann mir trotzdem jemand erklären, was da genau beim Iterieren passiert.
Mal die Frage vorweg:
Deine Schleife hat als Bedingung Iterator#hasNext, und das gibt eben zurück, ob der Iterator einen "nächsten" Wert hat.
Zu Beginn steht der Iterator vor Element 0, solange die zugrunde liegende Liste also nicht leer ist, hat er ein nächstes Element und gibt true zurück. hasNext ändert aber nichts an der Position, er steht auch danach weiterhin vor Position 0, ebenso beim zweite und dritten Aufruf.
next würde an der Position was ändern, next ist aber genau die Funktion, die eine ConcurrentModificationException werfen würd.
Ich sag es gleich im Vorfeld: Es gibt bestimmt einfache Methoden sowas zu machen, aber das war meine Idee und wollte es so umsetzten. Für Vorschläge bin ich aber dennoch offen
Um bei deiner Idee zu bleiben: du kannst ListIterator#add nutzen, um ein Element nach einem anderen einzufügen.
Statt for-each ListIterator zum iterieren nutzen, und dann dessen add-Methode:
Java:
for (ListIterator<String> iter = stringCollection.listIterator(); iter.hasNext(); ) {
String current = iter.next();
if (s.equals(firstChar)) {
iter.add(userEntry);
break;
}
}
myContent.refresh();
Also irgendwie ist das, was Du machst, extrem Konfus.
Du gehst alle Elemente einer Menge durch. Wenn bei einem Element der Anfangsbuchstabe korrekt ist, dann fügst Du das Element erneut ein (Dann hast Du es zwei Mal in der Liste)... Da Du dies immer weiter machst, verdoppelst Du die Kopie auch wieder und dann die Kopie der Kopie und dann ......
Also was Du machen willst ist doch eher etwas wie folgt:
- Du hast eine komplette Liste. Diese ist aber nur im Hintergrund (Unabhängig davon, was DU anzeigst und was nicht)
- Wenn Du kein erstes Zeichen hast, dann sind alle Element der Liste auch in der Liste, die angezeigt wird.
- Wenn Du ein erstes Zeichen bekommst, dann gehst Du die angezeigte Liste durch und löschst alle Elemente, bei denen das erste Zeichen unterschiedlich ist.
- Wenn sich das erste Zeichen ändert, dann löscht Du alle Zeichen und fügst von der kompletten liste alle Elemente ein, die passen.
Der letzte Punkt kann aber generell gemacht werden. Und das alles geht recht gut mit Streams, d.h. wenn Du eine Liste hast, dann kannst Du diese sortieren (sort Aufruf) und du kannst diese filtern (filter Aufruf) ... damit wird das fast ein Einzeiler...
Oder habe ich missverstanden, was Du genau machen willst?
Vielen Dank. Jetzt habe ich es verstanden. Ich habe tatsächlich die Funktionsweise eines Iterators missverstanden. Ich dachte der durchläuft das ganze ähnlich wie eine Schleife. Aber da er immer vor Index 0 ist, ist das natürlich eine Endlosschleife.
In der Doku kann man aber auch mit einer anderen Methode des Iterators die Elemente durchgehen. Damit wären ja, wie in meinem Falle die Strings gemeint, wenn ich das richtig verstanden habe.
@kneitzel
Deinen zuerst angesprochenen Punkt, umgehe ich bis jetzt erfolgreich mit diesem Code:
Code:
for (String s : stringCollection) {
if (s.equals(userEntry)) {
return;
}
}
Mit deinen übrigen Punkten, hast du natürlich vollkommen Recht. Das ganze ist eher eine Trockenübung und mir ist bewusst, dass noch etliche Eventualitäten abgedeckt werden müsste.
Da ich nicht wusste, wie sich der Filter bei bestimmten Gegebenheiten verhält, wollte ich etwas eigenes bauen.
Filter habe ich aber bereits in dem Alphabet angewendet, dass ich der Liste hinzugefügt habe. Das habe ich so gemacht
Vielen Dank. Jetzt habe ich es verstanden. Ich habe tatsächlich die Funktionsweise eines Iterators missverstanden. Ich dachte der durchläuft das ganze ähnlich wie eine Schleife. Aber da er immer vor Index 0 ist, ist das natürlich eine Endlosschleife.
In der Doku kann man aber auch mit einer anderen Methode des Iterators die Elemente durchgehen. Damit wären ja, wie in meinem Falle die Strings gemeint, wenn ich das richtig verstanden habe.
Das durchgehen beim Iterator trennt sich in zwei Dinge: hasNext und next, letzteres gibt das jeweils nächste Element zurück und schaltet weiter, damit geht das dann wie mit einer Schleife =)
Ich hatte daran gedacht, dass Du es in etwa so lösen könntest:
Java:
// unsortedElements: Ethält alle Elemente und ist z.B. ein List<String>
// filter ist Character und kann null sein, wenn nicht gefiltert werden soll.
// shownItems wäre dann die Liste mit Elementen, die angezeigt werden sollen.
shownItems = unsortedElements.stream()
.filter(i -> filter==null ? true : i.startsWith(""+filter))
.sorted(Comparator.naturalOrder())
.collect(Collectors.toList());
Das war in etwa, das ich so im Sinn hatte. Hier aufgeteilt in 4 Zeilen zur besseren Lesbarkeit ...
Ich danke euch. Ihr habt mir sehr weiter geholfen.
@kneitzel
Ich denke ich werde deine Variante nehmen. Das was du da geschrieben hast, wollte ich auf die Umständliche Art machen
Solche Gebilde an Code habe ich ehrlich gesagt bis jetzt gemieden, da ich bis jetzt der Meinung war, dass ich erstmal den regulären Weg lerne und mich dann mit Lambda Ausdrücke befasse.
Aber ich muss immer wieder feststellen, dass diese das Leben oftmals ungemein erleichtern. Mein ganzes Anliegen, in wenigen Zeilen verpackt.
Ist das denn wirklich das, was du brauchst?
Ursprünglich wolltest du ja den Nutzer neue Einteäge hinzufügen lassen - das ist jetzt eher das Filtern aller Einträge nach einem vom Nutzer kommenden Filter.
Solche Gebilde an Code habe ich ehrlich gesagt bis jetzt gemieden, da ich bis jetzt der Meinung war, dass ich erstmal den regulären Weg lerne und mich dann mit Lambda Ausdrücke befasse.
Naja. Ich brauche beides. Der Nutzer fügt etwas hinzu und in der Liste wird es dann bereits sortiert angezeigt. Der Eintrag soll ja dann gleich an die richtige Stelle kommen.
Ich werde das mal so kombinieren wie ihr beide das beschrieben habt und mir vor allen die Lambdas näher anschauen.