Swing DefaultListModel braucht zu lange, um Wert zu setzen

Kweenix

Mitglied
Hallo,
ich schreibe momentan einen Vokabeltrainer.
Er beinhaltet ~6000-7000 Vokabeln. Wenn ich eine Vokabel hinzufüge oder entferne, wird ein DefaultListModel geleert und anschließend werden alle Vokabeln neu sortiert neu hinzugefügt. Doch dies dauert mir zu lange (~15 Sekunden).
Ich habe das einmal mit zwei Instants vor und nach dem Hinzufügen gemessen und mir die Zeit in Nanosekunden ausgeben lassen. Am Anfang braucht jede ~ 50. Vokabel um die 5000000 Nanosekunden. Doch dieser Abstand verändert sich während der foreach Schleife, sodass am Ende jede Vokabel ca. 5000000-11000000 Nanosekunden braucht, um hinzugefügt zu werden. (Das Hinzufügen dauert genau so lange, wenn ich einen leeren String hinzufüge.)
Jetzt möchte ich das gerne vermeiden.
Kann mir dazu jemand helfen?
Dankeschön schonmal;)
Niklas
 

Thallius

Top Contributor
Ja, füge halt einfach nur die neue hinzu oder lösche enterne nur eine alte. Warum soll denn deswegen das Ganze Modell neu erstellt werden?
 

Thallius

Top Contributor
Du kannst es doch gleich an die richtige Stelle einfügen... klar. Da Must du tatsächlich selber die Stelle rausfinden und kannst nicht einfach eine fertig List.sort Routine aufrufen aber manchmal muss man tatsächlich selber Code schreiben als Programmierer....
 

MoxxiManagarm

Top Contributor
aber manchmal muss man tatsächlich selber Code schreiben als Programmierer....

Ich stimme zu, dass er was Programmieren muss. Aber es muss nicht zwingend das Einfügen an der richtigen Stelle sein. DefaultListModel ist an der Stelle aber auch nicht unbedingt geeignet. Probiere mal:

Java:
import java.util.TreeSet;

import javax.swing.AbstractListModel;

class SortedListModel<T> extends AbstractListModel<T> {
    private TreeSet<T> model;

    public SortedListModel() {
        model = new TreeSet<>();
    }

    @Override
    public int getSize() {
        return model.size();
    }
 
    public void add(T element) {
        if (model.add(element)) {
            int pos = model.headSet(element).size();
            fireContentsChanged(this, pos, pos);
        }
    }

    @Override
    public T getElementAt(int index) {
        return ((T[])model.toArray())[index];
    }
}

Kleiner Tester dazu:
Java:
import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

public class Tester extends JFrame {

    public Tester() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
     
        SortedListModel<String> model = new SortedListModel<>();
        JList<String> list = new JList<>(model);
        JScrollPane pane = new JScrollPane(list);
     
        add(pane, BorderLayout.CENTER);
     
        JTextField input = new JTextField();
        input.addActionListener(ae -> {
            model.add(input.getText());
            input.setText("");
        });
     
        add(input, BorderLayout.NORTH);
     
        for(int i = 1; i <= 10000; i++) {
            model.add("" + i);
        }
     
        pack();
    }
 
    public static void main(String[] args) {
        new Tester().setVisible(true);
    }
}

Das absolut Schnellste ist es mit 10000 Elementen auch nicht mehr, aber noch weit weg von 15 Sekunden.

Da Must du tatsächlich selber die Stelle rausfinden und kannst nicht einfach eine fertig List.sort Routine aufrufen
Mit einer Ähnlichen Model Implementierung würde auch das theoretisch gehen.
 
Zuletzt bearbeitet:

Flown

Administrator
Mitarbeiter
Und jetzt zeigt man noch das Optimum her:
Java:
class SortedListModel<T extends Comparable<? super T>> extends AbstractListModel<T> {
  private List<T> model = new ArrayList<>();
  
  @Override
  public int getSize() {
    return model.size();
  }
  
  public void add(T element) {
    int index = Collections.binarySearch(model, element);
    int insertionPoint = index < 0 ? -index - 1 : index;
    model.add(insertionPoint, element);
    fireIntervalAdded(this, insertionPoint, insertionPoint);
  }
  
  @Override
  public T getElementAt(int index) {
    return model.get(index);
  }
}
 

Kweenix

Mitglied
Danke erstmal für die vielen Antworten!:D
Ich habe noch ein wenig an dem Code rumgebastelt und jetzt funktioniert es!
Kann mir noch einer erklären, wieso das DefaultListModel meine Aufgabe nicht richtig erledigt. Manchmal erledigt der Computer meine Aufgabe nämlich so schnell, wie ich es will und manchmal dauert es länger(dieselbe Methode). Wäre supii, wenn mir da nochmal wer auf die Sprünge helfen könnte!

P.S.: Ich bin neu hier und wollte wissen, ob man das Thema irgendwie auf gelöst oder so ähnlich stellen kann?
 
Zuletzt bearbeitet:

Flown

Administrator
Mitarbeiter
P.S.: Ich bin neu hier und wollte wissen, ob man das Thema irgendwie auf gelöst oder so ähnlich stellen kann?
Gibts bei der Forensoftware nur als add-on und ist nicht installiert.
Kann mir noch einer erklären, wieso das DefaultListModel meine Aufgabe nicht richtig erledigt. Manchmal erledigt der Computer meine Aufgabe nämlich so schnell, wie ich es will und manchmal dauert es länger(dieselbe Methode). Wäre supii, wenn mir da nochmal wer auf die Sprünge helfen könnte!
Was heißt hier nicht richtig erledigt. Aber wenn du ständig 70000 Einträge löscht, dann hinzufügst, UI updates rausjagst (pro add-OP) und dann noch sortierst, läppert sich das schon an Operationen zusammen.
Du hast auch nicht wirklich gezeigt wie dein Code aussieht, vielleicht ist da auch noch etwas anderes gelaufen.
Zumindest mit meinen Modell hast du immer den gleichen Stock an Grunddaten. Es wird nur jeweils 1 eingefügt (Suchen ist O(log2(n)) und einfügen selbst O(n) - Liegt an der ArrayList) und 1 kleines Update für die UI gesendet.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G DefaultListModel für JList AWT, Swing, JavaFX & SWT 2
T Generische Klasse in JList über DefaultListModel AWT, Swing, JavaFX & SWT 1
S JList ist leer, aber DefaultListModel hat die Daten? AWT, Swing, JavaFX & SWT 9
E JList /DefaultListModel mit Datenbank verbinden AWT, Swing, JavaFX & SWT 10
M JList mit DefaultListModel und listener AWT, Swing, JavaFX & SWT 4
P DefaultListModel - jList - getSelectedIndex AWT, Swing, JavaFX & SWT 4
J cast ListModel zu DefaultListModel AWT, Swing, JavaFX & SWT 3
B Swing JPanel in Abhängigkeit von DefaultListModel Instanz neu zeichnen AWT, Swing, JavaFX & SWT 3
X Doppelte Daten in DefaultListModel unterbinden AWT, Swing, JavaFX & SWT 3
hdi JList + DefaultListModel = Race Condition :( AWT, Swing, JavaFX & SWT 12
S JList mit DefaultListModel befüllt, wie Objekte selektieren? AWT, Swing, JavaFX & SWT 3
N Braucht man fxml AWT, Swing, JavaFX & SWT 3
Furtano AWT paint braucht ein Graphics Objekt ? AWT, Swing, JavaFX & SWT 2
G Swing Wieso braucht man nach setVisible mal ein revalidate und mal nicht? AWT, Swing, JavaFX & SWT 8
J Schulprojekt und braucht hilfe AWT, Swing, JavaFX & SWT 54
L JFileChooser braucht lang zum öffnen AWT, Swing, JavaFX & SWT 2
R JTable Darstellen der selektierten Zelle braucht lange AWT, Swing, JavaFX & SWT 7
K noob braucht unterstützung AWT, Swing, JavaFX & SWT 2
D Grafikeinsteiger sucht/braucht Hilfe. Wäre Nett ! AWT, Swing, JavaFX & SWT 3
P Warum braucht mein kleines Programm 20 MB Speicher? AWT, Swing, JavaFX & SWT 13
MadMax2506 Swing JTable lädt sehr lange AWT, Swing, JavaFX & SWT 1
S PDF Printjob lange in Warteschlange AWT, Swing, JavaFX & SWT 0
G EventDispatchThread und lange Berechnungszeit AWT, Swing, JavaFX & SWT 3
J Zu lange Wörter umbrechen in JLabel AWT, Swing, JavaFX & SWT 5
E 3D-Grafik JOGL (lädt sehr lange) AWT, Swing, JavaFX & SWT 20
A Darstellung dauert zu lange. Wie rest verzögern? AWT, Swing, JavaFX & SWT 7
V Swing remove(Component) blockiert Thread sehr lange. AWT, Swing, JavaFX & SWT 6

Ähnliche Java Themen

Neue Themen


Oben