2015-10-19 6 views
6

In Java ist BigInteger unveränderlich, aber ich möchte verstehen, warum es oft verwendet wird, um eine Menge Berechnungen durchzuführen, die viele Objekte erzeugen können. Es fühlt sich irgendwie intuitiv an, es nicht unveränderlich zu machen. Die Situation, die mir in den Sinn kommt, ist etwas von String-Operationen und dann die Option von StringBuilder. Sollte es ein unveränderbares Gegenstück zu BigInteger geben? Ich denke, dass es in vielen Situationen nützlich sein könnte.Warum ist BigInteger in Java so konzipiert, dass es unveränderbar ist?

Edit: Ich kenne die Vorteile der Unveränderlichkeit und wie es in vielen Fällen vorteilhaft ist. Ich wollte nur die Vorteile von BigInteger verstehen. Ich habe BigInteger verwendet, um die Fakultät für große Zahlen zu berechnen. Also hätte ich einen veränderbaren BigInteger vorgezogen. In ähnlicher Weise wird BigInteger für Berechnungen verwendet, bei denen das Ergebnis viel größer als int ist. Für andere Fälle gibt es BigDecimal.

+0

Sie können 'BitSet' als (Art-) veränderbaren' BigInteger' verwenden. –

+1

Kurzlebige Objekte sind billig und unveränderliche Objekte haben viele Vorteile. – chrylis

+0

* "Ich denke, es könnte in vielen Situationen nützlich sein." * ... es könnte für einige wirklich super-Performance kritische Situationen wichtig sein, aber wahrscheinlich nicht so viele Situationen insgesamt wie Sie vermuten. Wenn Sie jedoch einen Profiling-erprobten performancekritischen Codeblock haben, kann eine änderbare Companion-Klasse die Antwort sein. – scottb

Antwort

11

Effective Java von Josh Bloch erklärt die Vorteile von unveränderlichen Klassen, in "Punkt 15: Minimieren Mutability":

unveränderliche Klassen sind leichter zu entwerfen, implementieren und verwenden als wandelbar Klassen. Sie sind weniger anfällig zu Fehler und sind sicherer.

Ein unveränderliches Objekt ist einfach, da das Objekt nur in einem Zustand existieren kann - der Staat es erstellt wurde Einfacher Code neigt wenige Fehler zu haben.. Da das Objekt nicht verändert werden kann, ist es auch thread-sicher ohne externe Synchronisation.

Bloch befaßt dich mit dem Performance-Problem mit unveränderlichen Klassen, mit BigInteger als Beispiel:

Der einzige wirkliche Nachteil unveränderlicher Klassen ist, dass sie ein separates Objekt für jeden eindeutigen Wert erfordern. Das Erstellen dieser Objekte kann sehr kostenintensiv sein, besonders wenn sie groß sind. [...]

Intern kann die unveränderliche Klasse beliebig clever sein. Zum Beispiel hat BigInteger eine Paket-private veränderbare "Begleiter-Klasse", die verwendet wird, um mehrstufige Operationen wie die modulare Exponentiation zu beschleunigen. Es ist viel schwieriger, die veränderbare Begleitklasse zu verwenden, als BigInteger für alle oben genannten Gründe zu verwenden, aber glücklicherweise müssen Sie das nicht: Die Entwickler von BigInteger haben die harte Arbeit für Sie erledigt.

So intern BigInteger bereits einige Optimierung für Sie. Wenn Sie wirklich eine veränderbare BigInteger möchten, können Sie eine BitSet verwenden, aber beachten Sie, dass dies wahrscheinlich Ihren Code komplexer macht - und mehr fehleranfällig. Sie sollten die einfachste mögliche Lösung verwenden (BigInteger), es sei denn, Sie sind sicher, dass die Verwendung einer veränderbaren Version Ihnen einen spürbaren Leistungsgewinn bringt (siehe auch "Artikel 55: Optimieren Sie vernünftig" aus demselben Buch).

Verwandte Themen