Java-Sammlung einfügen: Set vs. List

8

Ich denke darüber nach, eine Sammlung mit einer großen Anzahl einzigartiger Objekte zu füllen. Wie hoch sind die Kosten einer Einfügung in einem Set (zB HashSet) im Vergleich zu einer List (zB ArrayList)?

Mein Gefühl ist, dass die doppelte Eliminierung in Mengen einen leichten Overhead verursachen kann.

    
Will 18.05.2011, 11:52
quelle

7 Antworten

10

Es gibt keine "doppelte Eliminierung" wie zum Beispiel einen Vergleich mit allen existierenden Elementen. Wenn Sie in einen Hash-Satz einfügen, handelt es sich wirklich um ein Dictionary mit Hash-Code. Es gibt keine doppelte Überprüfung, es sei denn, es gibt bereits Elemente mit demselben Hash-Code. Angesichts einer vernünftigen (gut verteilten) Hash-Funktion ist es nicht so schlimm.

Wie Will bemerkt hat, ist HashSet wegen der Dictionary-Struktur wahrscheinlich etwas langsamer als ein ArrayList (es sei denn, Sie wollen "zwischen" vorhandene Elemente einfügen). Es ist auch ein bisschen größer. Ich bin mir nicht sicher, ob das ein wesentlicher Unterschied ist.

    
Konrad Garus 18.05.2011, 11:56
quelle
4

Wenn Sie sicher sind werden Ihre Daten eindeutig sein, verwenden Sie eine Liste. Sie können ein Set verwenden, um diese Regel durchzusetzen .

Sets sind schneller als Listen wenn Sie einen großen Datensatz haben, während der inverse ist true für kleinere Datensätze. Ich habe diese Behauptung nicht persönlich getestet.

Welche Art von Liste?
Überlegen Sie auch, welche Liste Sie verwenden möchten. VerknüpfteListen können Elemente schneller hinzufügen oder entfernen.

ArrayLists sind schneller bei wahlfreiem Zugriff ( for loops, usw.), aber dies kann mit dem Iterator einer LinkedList umgangen werden. ArrayLists sind viel schneller bei: list.toArray() .

    
Redandwhite 18.05.2011 12:01
quelle
3

Sie haben Recht: Mengenstrukturen sind von Natur aus komplexer, um Duplikate zu erkennen und zu eliminieren. Ob dieser Overhead für Ihren Fall signifikant ist, sollte mit einem Benchmark getestet werden.

Ein weiterer Faktor ist die Speichernutzung. Wenn Ihre Objekte sehr klein sind, kann der Speicherbedarf, der durch die Mengenstruktur eingeführt wird, erheblich sein. Im extremsten Fall ( TreeSet<Integer> vs. ArrayList<Integer> ) kann die Mengenstruktur mehr als 10 mal so viel Speicher benötigen.

    
Michael Borgwardt 18.05.2011 11:58
quelle
2

Wenn das Ziel die Eindeutigkeit der Elemente ist, sollten Sie eine Implementierung von java.util.Set Schnittstelle. Die Klasse java.util.HashSet und java.util.LinkedHashSet haben O ( alpha ) (nahe bei O (1) im besten Fall) Komplexität für einfügen, löschen und enthält überprüfen.

ArrayList haben O ( n ) für Objekt (nicht Index) enthält überprüfen (Sie müssen durch die gesamte Liste scrollen) und Einfügen (wenn die Einfügung nicht im Ende der Liste ist, Sie müssen das gesamte Unterstreichungsfeld verschieben).

Sie können LinkedHashSet verwenden, die die Reihenfolge der Einfügung beibehalten und die gleiche Potenz von HashSet haben (belegt nur ein bisschen mehr Speicher).

    
Alberto 18.05.2011 12:11
quelle
1

Sie müssen konkrete Implementierungen vergleichen (zum Beispiel HashSet mit ArrayList ), weil die abstrakten Schnittstellen Set / List nicht wirklich etwas über die Leistung aussagen.

Das Einfügen in HashSet ist eine ziemlich billige Operation, solange die hashCode() des einzufügenden Objekts gesund ist. Es ist immer noch etwas langsamer als ArrayList , da es sich bei der Einfügung um eine einfache Einfügung in ein Array handelt (vorausgesetzt, Sie fügen am Ende ein und es gibt noch freien Platz; ich berücksichtige nicht die Größe des internen Arrays, da die gleichen Kosten anfallen auch zu HashSet ).

    
Joachim Sauer 18.05.2011 11:55
quelle
1

Ich glaube nicht, dass Sie dieses Urteil einfach über die Kosten des Baus der Sammlung fällen können. Andere Dinge, die Sie berücksichtigen müssen, sind:

  • Ist das Eingabe-Dataset geordnet? Gibt es eine Anforderung, dass die Ausgabedatenstruktur die Anzeigenreihenfolge beibehält?
  • Besteht die Anforderung, dass die Ausgabedatenstruktur basierend auf Elementwerten? (/?) geordnet (oder neu geordnet) wird?
  • Wird die Ausgabedatenstruktur nachträglich geändert? Wie?
  • Muss die Ausgabedatenstruktur doppelt vorhanden sein, wenn andere Elemente nachträglich hinzugefügt werden?
  • Wissen Sie, wie viele Elemente sich wahrscheinlich im Eingabe-Dataset befinden?
  • Können Sie die Größe des Eingabe-Datasets messen? (Oder wird es über einen Iterator bereitgestellt?)
  • Ist die Speicherplatznutzung wichtig?

Diese können alle Ihre Wahl der Datenstruktur beeinflussen.

    
Stephen C 18.05.2011 12:12
quelle
1

Java-Liste:

Wenn Sie eine solche Anforderung nicht haben, müssen Sie doppelt halten oder nicht. Dann können Sie List statt Set verwenden.

List ist eine Schnittstelle im Collection-Framework. Was die Collection-Schnittstelle erweitert. und ArrayList, LinkedList ist die Implementierung der List-Schnittstelle.

Wann wird ArrayList oder LinkedList

verwendet?

ArrayList: Wenn Sie eine solche Anforderung haben, die in Ihrer Anwendung am meisten funktioniert, ist der Zugriff auf die Daten. Dann sollten Sie sich für ArrayList entscheiden. weil ArrayList RtandomAccess-Schnittstelle implementiert, die Marker-Schnittstelle ist. Aufgrund der Marker-Schnittstelle haben ArrayList die Möglichkeit, auf die Daten in O (1) -Zeit zuzugreifen. und Sie können ArrayList über LinkedList verwenden, wo Sie Daten entsprechend der Reihenfolge erhalten möchten.

LinkedList: Wenn Sie eine solche Anforderung haben, ist Ihre Arbeit meistens das Einfügen oder Löschen. Dann sollten Sie LinkedList über die ArrayList verwenden. Weil in InsertedList Insertion und Deletion in O (1) Zeit passieren, während in ArrayList es O (n) Zeit ist.

Java-Set:

Wenn Sie in Ihrer Anwendung Anforderungen haben, dass Sie keine Duplikate wünschen. Dann sollten Sie Set statt List wählen. Weil Set keine Duplikate speichert. Weil Set nach dem Hashing-Prinzip arbeitet. Wenn wir ein Objekt in Set hinzufügen, prüft es zunächst den Hash-Code des Objekts im Bucket, wenn ein Hash-Code gefunden wird, der in seinem Block vorhanden ist. Dann wird das Objekt nicht hinzugefügt.

    
Vpn_talent 23.11.2017 13:53
quelle

Tags und Links