Das Java-Team hat eine Menge großartiger Arbeit geleistet, um Hindernisse für die funktionale Programmierung in Java 8 zu beseitigen. Insbesondere die Änderungen an den java.util-Sammlungen ermöglichen die Verkettung von Transformationen in sehr schnelle Streaming-Vorgänge. In Anbetracht der guten Arbeit, die sie beim Hinzufügen erstklassiger Funktionen und funktionaler Methoden zu Sammlungen geleistet haben, warum konnten sie überhaupt keine unveränderlichen Sammlungen oder sogar unveränderlichen Sammlungsschnittstellen bereitstellen?
Ohne den vorhandenen Code zu ändern, kann das Java-Team jederzeit unveränderbare Schnittstellen hinzufügen, die mit den veränderlichen identisch sind, abzüglich der "set" -Methoden, und die vorhandenen Schnittstellen so erweitern, dass sie davon abweichen:
ImmutableIterable
____________/ |
/ |
Iterable ImmutableCollection
| _______/ / \ \___________
| / / \ \
Collection ImmutableList ImmutableSet ImmutableMap ...
\ \ \_________|______________|__________ |
\ \___________|____________ | \ |
\___________ | \ | \ |
List Set Map ...
Sicher, Operationen wie List.add () und Map.put () geben derzeit einen booleschen oder vorherigen Wert für den angegebenen Schlüssel zurück, um anzuzeigen, ob die Operation erfolgreich war oder fehlgeschlagen ist. Unveränderliche Sammlungen müssten solche Methoden als Fabriken behandeln und eine neue Sammlung mit dem hinzugefügten Element zurückgeben - was mit der aktuellen Signatur nicht kompatibel ist. Dies könnte jedoch durch die Verwendung eines anderen Methodennamens wie ImmutableList.append () oder .addAt () und ImmutableMap.putEntry () umgangen werden. Die resultierende Ausführlichkeit würde durch die Vorteile der Arbeit mit unveränderlichen Auflistungen mehr als aufgewogen, und das Typsystem würde Fehler beim Aufrufen der falschen Methode verhindern. Im Laufe der Zeit könnten die alten Methoden veraltet sein.
Gewinne unveränderlicher Sammlungen:
- Einfachheit - Das Denken in Bezug auf Code ist einfacher, wenn sich die zugrunde liegenden Daten nicht ändern.
- Dokumentation - Wenn eine Methode eine unveränderliche Sammlungsschnittstelle verwendet, wissen Sie, dass diese Sammlung nicht geändert wird. Wenn eine Methode eine unveränderliche Auflistung zurückgibt, wissen Sie, dass Sie sie nicht ändern können.
- Parallelität - unveränderliche Sammlungen können sicher über mehrere Threads hinweg gemeinsam genutzt werden.
Als jemand, der Sprachen gekostet hat, die Unveränderlichkeit annehmen, ist es sehr schwer, in den Wilden Westen der grassierenden Mutation zurückzukehren. Die Sammlungen von Clojure (Sequenzabstraktion) bieten bereits alles, was Java 8-Sammlungen bieten, sowie Unveränderlichkeit (obwohl möglicherweise zusätzlicher Speicher und Zeit aufgrund synchronisierter verknüpfter Listen anstelle von Streams benötigt wird). Scala hat sowohl veränderbare als auch unveränderliche Sammlungen mit einer ganzen Reihe von Operationen, und obwohl diese Operationen eifrig sind, gibt der Aufruf von .iterator eine träge Sichtweise (und es gibt andere Möglichkeiten, sie träge zu bewerten). Ich sehe nicht, wie Java ohne unveränderliche Sammlungen weiter konkurrieren kann.
Kann mich jemand auf die Geschichte oder Diskussion darüber hinweisen? Sicherlich ist es irgendwo öffentlich.
const
Sammlungen hast
Collections.unmodifiable*()
sind für. Aber behandeln Sie diese nicht als unveränderlich, wenn sie nicht sind
ImmutableList
in diesem Diagramm nimmt, können Leute in einem veränderlichen überschreiten List
? Nein, das ist eine sehr schlimme Verletzung von LSP.