608 Stimmen

Warum gibt es in Java keine SortedList?

In Java gibt es die SortedSet y SortedMap Schnittstellen. Beide gehören zu den Java Collections-Framework und bieten einen geordneten Zugang zu den Elementen.

Nach meinem Verständnis gibt es jedoch keine SortedList in Java. Sie können verwenden java.util.Collections.sort() um eine Liste zu sortieren.

Haben Sie eine Idee, warum sie so gestaltet ist?

3 Stimmen

9 Stimmen

Welches Ergebnis erwarten Sie also, wenn Sie ein Element in der Mitte der Liste einfügen?

6 Stimmen

@bestsss Es wäre durchaus möglich, eine SortedList-Klasse zu haben, die nicht die java.util.List-Schnittstelle implementiert. Lesen Sie die Frage als eine Anfrage, warum es keine Datenstruktur gibt, die die gewünschte Funktionalität unterstützt. Lassen Sie sich nicht von unbedeutenden Details wie der Namensgebung ablenken.

11voto

Jim Pekarek Punkte 7220

Für alle Neulinge: Seit April 2015 hat Android nun eine SortierteListe Klasse in der Support-Bibliothek, die speziell für die Arbeit mit RecyclerView . Hier ist die ブログ記事 darüber.

1 Stimmen

Es ist erwähnenswert, dass zum Zeitpunkt dieses Kommentars Androids SortedList keine Unterstützung für onItemMoved()-Funktionalität mit RecyclerView bietet. Schreiben meine eigene SortedList, die weniger effizient ist, ist, was ich tun musste, um die Einschränkungen zu umgehen.

4voto

Ingo Punkte 35534

Ein weiterer Punkt ist die Zeitkomplexität von Einfügeoperationen. Bei einer Listeneinfügung erwartet man eine Komplexität von O(1). Bei einer sortierten Liste kann dies jedoch nicht garantiert werden.

Und der wichtigste Punkt ist, dass Listen nichts über ihre Elemente aussagen. Sie können zum Beispiel Listen von Dingen erstellen, die nicht equals o compare .

0 Stimmen

Sie können eine Liste mit O(logn) insert/delete/find/contains haben, aber nicht mit get(int).

3 Stimmen

Der letzte Punkt ist nicht wirklich eine gute Erklärung. Sie können eine SortedSet von Dingen, die nicht umgesetzt werden Comparable . Siehe dieser TreeSet-Konstruktor .

1 Stimmen

@Alderath - vielleicht war meine Formulierung zu schwach. Dennoch gilt die Beobachtung, dass Elemente von Mengen und Schlüssel von Bäumen zumindest für die Gleichheit vergleichbar sein müssen, während Listenelemente dies nicht müssen. Ob die Ordnungs-/Gleichheitsbeziehung für Sets und Trees in einem Comparator oder anderswo implementiert ist, ist unerheblich - aber man braucht einen.

3voto

Costi Ciudatu Punkte 35188

Man muss sich das so vorstellen: Die List Schnittstelle hat Methoden wie add(int index, E element) , set(int index, E element) . Der Vertrag sieht vor, dass Sie ein einmal hinzugefügtes Element an der Position X wiederfinden, wenn Sie nicht vorher Elemente hinzufügen oder entfernen.

Würde eine Listenimplementierung Elemente in einer anderen Reihenfolge als auf der Grundlage des Indexes speichern, würden die oben genannten Listenmethoden keinen Sinn ergeben.

3voto

Marcono1234 Punkte 4017

Wenn Sie nach einer Möglichkeit suchen, Elemente zu sortieren, aber auch effizient nach Index auf sie zugreifen zu können, können Sie Folgendes tun:

  1. Verwenden Sie eine Zufallszugriffsliste für die Speicherung (z. B. ArrayList )
  2. Sorgen Sie dafür, dass sie immer sortiert ist

Um dann ein Element hinzuzufügen oder zu entfernen, können Sie Collections.binarySearch um den Einfüge-/Entfernungsindex zu erhalten. Da Ihre Liste einen zufälligen Zugriff implementiert, können Sie die Liste mit dem ermittelten Index effizient ändern.

/**
 * @deprecated
 *      Only for demonstration purposes. Implementation is incomplete and does not 
 *      handle invalid arguments.
 */
@Deprecated
public class SortingList<E extends Comparable<E>> {
    private ArrayList<E> delegate;

    public SortingList() {
        delegate = new ArrayList<>();
    }

    public void add(E e) {
        int insertionIndex = Collections.binarySearch(delegate, e);

        // < 0 if element is not in the list, see Collections.binarySearch
        if (insertionIndex < 0) {
            insertionIndex = -(insertionIndex + 1);
        }
        else {
            // Insertion index is index of existing element, to add new element 
            // behind it increase index
            insertionIndex++;
        }

        delegate.add(insertionIndex, e);
    }

    public void remove(E e) {
        int index = Collections.binarySearch(delegate, e);
        delegate.remove(index);
    }

    public E get(int index) {
        return delegate.get(index);
    }
}

(Eine ausführlichere Implementierung finden Sie in diese Antwort )

2voto

Syam Punkte 1182

Die erste Zeile in der Listen-API besagt, dass es sich um eine geordnete Sammlung (auch als Sequenz bezeichnet) handelt. Wenn Sie die Liste sortieren, können Sie die Reihenfolge nicht beibehalten, daher gibt es in Java keine TreeList.
Wie API sagt, wurde Java List von Sequence inspiriert und siehe die Sequence-Eigenschaften http://en.wikipedia.org/wiki/Sequence_(Mathematik

Das bedeutet nicht, dass Sie die Liste nicht sortieren können, aber Java hält sich strikt an seine Definition und bietet standardmäßig keine sortierten Versionen von Listen an.

2 Stimmen

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X