Wie verwende ich ListBuffer in scala?

8

Ich habe eine Situation, in der ich eine einzelne Elementliste an eine Methode übergebe. Innerhalb dieser Methode wird das einzelne Element in der Liste um eins erhöht. Nach dem Methodenaufruf wird also das erste Element der Liste geändert (um eins erhöht).

Code ist wie folgt:

%Vor%

......

%Vor%

Natürlich funktioniert der obige Code in Scala nicht. Ich schaute auf ListBuffer , aber ich finde das scala doc schwer zu finden Folgen. Scala doc ist in zwei Gruppen unterteilt: Typ Mitglieder und Wert Mitglieder. In type member gibt es die Klasse WithFiler und value members hat viele Methoden. Wie kann ich WithFiler verwenden (wahrscheinlich nicht direkt mit dieser Frage verbunden, aber ich möchte verstehen, wie man scala doc benutzt).

ListBuffer scheint die richtige Lösung für dieses Problem zu sein, wenn ich eine sehr hohe Leistung haben will (die someMethod wird Millionen Mal aufgerufen) (korrigieren Sie mich, wenn ich falsch liege).

Wie löst man das obige Problem, wenn ListBuffer der richtige Listentyp ist und wenn nicht, was ist die Lösung?

    
rjc 04.07.2011, 10:15
quelle

5 Antworten

10

In scala, der Ausdruck:

%Vor%

wird wie folgt umgeschrieben:

%Vor%

Die Methode update ist nicht für den Obertyp List definiert, da Listen unveränderlich sein können. Dies ist jedoch der Typ des Funktionsarguments.

Sie müssen also nur ListBuffers (oder einen veränderlichen Supertyp) verwenden:

%Vor%

Wenn Sie auf Elemente nach Indizes zugreifen müssen, verwenden Sie stattdessen stattdessen ArrayBuffer . Es sollte als Java ArrayList funktionieren.

Schließlich, wenn Sie nicht über WithFilter sachen nachdenken müssen. Verwenden Sie einfach die Methode filter .

    
paradigmatic 04.07.2011, 10:28
quelle
5

Wenn die Leistung ein Hauptziel ist und die maximale Größe der Sammlung bekannt ist, können Sie Array verwenden, das sich direkt auf das Java-Array bezieht.

    
incrop 04.07.2011 10:39
quelle
5

Das hat den Geruch einer vorzeitigen Mikrooptimierung darüber.

Es gibt zwar berechtigte Gründe für die Verwendung von Änderbarkeit (einschließlich Optimierung), aber Sie haben nicht angegeben, warum Sie glauben, dass Ihre Verwendung gültig ist, oder das größere Problem, das Sie lösen möchten. Insbesondere sind unveränderliche Listen sehr effizient, wenn sie das Ende nehmen und einen neuen Kopf voranstellen - 100% der Nicht-Kopf-Elemente werden zwischen der ursprünglichen und der neuen Liste geteilt.

Wie Sie sehen, ist die sauberste Lösung für Ihre Anforderungen,% ce_de% zu vergessen, bei einer unveränderlichen ListBuffer zu bleiben und List zu implementieren, ohne auf Nebenwirkungen zurückzugreifen.

%Vor%

Wenn andererseits ein Performance-Hotspot ist und Sie keine Möglichkeit finden, die Leistung zu verbessern, indem Sie den Algorithmus ändern, sollten Sie ein someMethod

Array ist der einzige vereinheitlichte Sammlungstyp auf der JVM. Daher können Sie direkt mit Grundelementen in einem Array arbeiten und das Boxing / Unboxing vermeiden, mit dem andere Auflistungstypen zu kämpfen haben.

Der Vorteil hier hat nichts mit Veränderbarkeit vs. Unveränderlichkeit zu tun; Die Leistungskosten des Unboxing / Boxens sind weit höher als die Leistungskosten (falls vorhanden) der Verwendung einer unveränderlichen Liste.

    
Kevin Wright 04.07.2011 13:40
quelle
2

Sie können das obige natürlich umschreiben, um ListBuffer zu verwenden, aber wenn Sie nur eine semantische Call-by-Reference Semantik für ein einzelnes Int wollen, ist das nicht unbedingt die effizienteste Lösung. ArrayBuffer sollte ein bisschen besser sein. Sie könnten auch so etwas tun:

%Vor%

Ich versuche normalerweise, meinen Code neu zu schreiben, um zu vermeiden, veränderbare Sammlungen für diese Art von Dingen zu verwenden. Zum Beispiel könnten Sie einfach den neuen Wert zurückgeben:

%Vor%     
Nate Nystrom 04.07.2011 10:37
quelle
2

Wenn Sie ListBuffer verwenden möchten, müssen Sie nur das Wort "List" in Ihrem Code für "ListBuffer" ersetzen. Allerdings würde ich die Nebeneffekt-Funktion (Ihr someMethod: Unit) komplett vermeiden, wie es naten nahe legt.

ListBuffer hat "hohe Leistung" - der Hauptzweck ist jedoch das Hinzufügen von Elementen / Ändern der Sammlung. Wenn ich es richtig verstanden habe, aktualisieren Sie das Objekt in einer Objektkollektion millionenfach - Array ist dafür ausreichend.

    
Zdenek F 04.07.2011 11:52
quelle

Tags und Links