web-dev-qa-db-de.com

Vergleich von Leistung und Speicherzuordnung zwischen Liste und Satz

Ich möchte den Vergleich zwischen List und Set in Bezug auf Leistung, Speicherzuordnung und Benutzerfreundlichkeit kennen.

Wenn ich keine Anforderung habe, die Eindeutigkeit in der Liste der Objekte beizubehalten, muss auch die Reihenfolge der Einfügung nicht beibehalten werden. Kann ich ArrayList und SortedSet/HashSet austauschbar verwenden? gerade Liste/Set?

P.S. Ich brauche auch keine Liste oder setze spezifische Funktionen, die von Java bereitgestellt werden .. Ich benutze List/Set anstelle von Array nur, weil sie ohne zusätzlichen Programmieraufwand dynamisch wachsen können.

44
Priyank Doshi

Wenn Sie sich nicht für die Reihenfolge interessieren und Elemente nicht löschen, dann hängt es wirklich davon ab, ob Sie Elemente in dieser Datenstruktur suchen müssen und wie schnell diese Suchvorgänge sein müssen.

Ein Element anhand eines Wertes in einer HashSet zu finden, ist O(1). In einer ArrayList ist es O(n).

Wenn Sie den Container nur zum Speichern mehrerer eindeutiger Objekte verwenden und am Ende (in beliebiger Reihenfolge) über sie hinweg iterieren, ist ArrayList wahrscheinlich die bessere Wahl, da dies einfacher und wirtschaftlicher ist.

39
NPE

HashSet verbraucht etwa 5,5 Mal mehr Speicher als ArrayList für die gleiche Anzahl von Elementen (obwohl sie beide noch linear sind) und weist eine wesentlich langsamere Iteration auf (allerdings mit den gleichen Asymptotika). Eine schnelle Google-Suche schlägt eine 2-3-fache Verlangsamung für HashSet Iteration gegenüber ArrayList vor.

Wenn Sie sich nicht für die Eindeutigkeit oder die Leistung von contains interessieren, verwenden Sie ArrayList.

65
Louis Wasserman

Wenn Sie nur Elemente hinzufügen und später iterieren möchten, ist ArrayList Ihre beste Wette, da sie den Arrays, die Sie ersetzen, am nächsten kommt. Es ist speichereffizienter als LinkedList oder eine beliebige Set-Implementierung, hat eine schnelle Einfügung, Iteration und Direktzugriff.

1
Marko Topolnik

Verwenden Sie HashSet, wenn Sie .contains(T) häufig verwenden müssen.

Beispiel:

private static final HashSet<String> KEYWORDS = Stream.of(new String[]{"if", "do", "for", "try", "while", "break", "return"}).collect(Collectors.toCollection(HashSet::new));

public boolean isKeyword(String str) {
     return KEYWORDS.contains(str);
}
0
Dave_cz

Wenn Sie vergleichen, ist die Suche zwischen List und Set aufgrund des unterstrichenen Hash-Algorithmus besser.

Im Falle einer Liste wird, im schlimmsten Fall, die Suche bis zum Ende durchgeführt .. __ Im Fall von Set wird aufgrund von Hashing und Bucket nur die Teilmenge durchsucht.

Anwendungsbeispiel: Hinzufügen von 1 zu 100_000 Integer zu ArrayList und HashSet . Suchen Sie jede ganze Zahl in ArrayList und HashSet.

Das Set dauert 9 Millisekunden, während die Liste 16232 Sekunden dauert.

private static void compareSetvsList(){
    List<Integer> list = new ArrayList<>() ;
    Set<Integer> set = new HashSet<>() ;

    System.out.println("Setting values in list and set .... ");
    int counter = 100_000  ;

    for(int i =0 ; i< counter ; i++){            
        list.add(i);
        set.add(i);
    }

    System.out.println("Checking time .... ");
    long l1 = System.currentTimeMillis();
    for(int i =0 ; i< counter ; i++) list.contains(i);

    long l2 = System.currentTimeMillis();
    System.out.println(" time taken for list : "+ (l2-l1));

    for(int i =0 ; i< counter ; i++)set.contains(i);

    long l3 = System.currentTimeMillis();
    System.out.println(" time taken for set : "+ (l3-l2));

    //      for 10000   time taken for list : 123        time taken for set : 4
    //      for 100000  time taken for list : 16232          time taken for set : 9
    //      for 1000000 time taken for list : hung       time taken for set : 26

}
0
Manoj

Wenn Sie nicht die Anforderung haben, eindeutige Elemente in collection zu haben, verwenden Sie einfach ArrayList, es sei denn, Sie haben sehr spezifische Anforderungen.

Wenn Sie in collection nur eindeutige Elemente haben müssen, verwenden Sie HashSet, sofern Sie keine besonderen Anforderungen haben.

In Bezug auf SortedSet (und dessen Implementierer TreeSet) gemäß JavaDoc:

Ein Set, das außerdem eine Gesamtreihenfolge für seine Elemente enthält. Die Elemente werden nach ihrer natürlichen Reihenfolge oder von einem Komparator geordnet, der normalerweise zum Erstellungszeitpunkt für sortierte Sätze bereitgestellt wird.

Das heißt, es ist auf ganz bestimmte Anwendungsfälle ausgerichtet, bei denen Elemente immer in einer set angeordnet werden sollten, die normalerweise nicht benötigt wird.

0
Yura