Unveränderliche Sammlung bedeutet, wie der Name schon sagt, dass die Sammlung nicht geändert werden kann. Die Datenelemente einer Sammlung werden zum Zeitpunkt der Erstellung bereitgestellt und können während des gesamten Lebenszyklus nicht geändert werden.
Warum unveränderliche Objekte verwenden? Unveränderliche Objekte haben die folgenden Vorteile:
1. Sie können sicher für unzuverlässige Client-Codebibliotheken verwendet werden, und diese Objekte können sicher in nicht vertrauenswürdigen Klassenbibliotheken verwendet werden.
2. Thread-sicher: unveränderlich Objekte sind in Multithreads sicher und haben keine Race Conditions
3. Es besteht keine Notwendigkeit, Variabilität zu unterstützen, und Sie können versuchen, Platz- und Zeitaufwand zu sparen. Alle unveränderlichen Sammlungsimplementierungen sind besser als veränderliche Sammlungen Speicher effizienter (Analyse)
4. Kann als Konstante verwendet werden und wird voraussichtlich auch in Zukunft unverändert bleiben
Unveränderliche Objekte können auf natürliche Weise als Konstanten verwendet werden, da sie von Natur aus unveränderlich sind . Es ist eine gute defensive Programmiertechnik, unveränderliche Objekte zu verwenden.
Implementierung unveränderlicher Sammlungen im JDK
Collections.unmodifiableXXX-Methoden werden im JDK bereitgestellt, um unveränderliche Sammlungen zu implementieren, aber es gibt zunächst einige Probleme:
[code]import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.junit.Test; public class ImmutableTest { @Test public void testJDKImmutable(){ List<String> list=new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); System.out.println(list); List<String> unmodifiableList=Collections.unmodifiableList(list); System.out.println(unmodifiableList); List<String> unmodifiableList1=Collections.unmodifiableList(Arrays.asList("a","b","c")); System.out.println(unmodifiableList1); String temp=unmodifiableList.get(1); System.out.println("unmodifiableList [0]:"+temp); list.add("baby"); System.out.println("list add a item after list:"+list); System.out.println("list add a item after unmodifiableList:"+unmodifiableList); unmodifiableList1.add("bb"); System.out.println("unmodifiableList add a item after list:"+unmodifiableList1); unmodifiableList.add("cc"); System.out.println("unmodifiableList add a item after list:"+unmodifiableList); } }
[code][a, b, c] [a, b, c] [a, b, c] unmodifiableList [0]:b list add a item after list:[a, b, c, baby] list add a item after unmodifiableList1:[a, b, c, baby]
1. Es ist umständlich und umständlich zu verwenden und Sie müssen diese Methode in jeder defensiven Programmierkopie verwenden
2. Es ist unsicher: Wenn Gibt es ein Objekt, das auf die ursprüngliche gekapselte Sammlungsklasse verweist, sind die von diesen Methoden zurückgegebenen Sammlungen nicht wirklich unveränderlich.
3. Geringe Effizienz: Da die Essenz der zurückgegebenen Datenstruktur immer noch die ursprüngliche Sammlungsklasse ist, sind ihr Betriebsaufwand, einschließlich der gleichzeitigen Änderungsprüfung, und der zusätzliche Datenraum in der Hash-Tabelle mit dem identisch Originalsammlung.
Guavas unveränderliche Sammlung
Guava bietet eine einfache und praktische Implementierung der unveränderlichen Version der Standard-Sammlungsklasse im JDK sowie Guavas eigene unveränderliche Implementierung einiger spezialisierter Sammlungsklassen. Wenn Sie eine Sammlungsklasse nicht ändern oder eine konstante Sammlungsklasse erstellen möchten, ist die Verwendung einer unveränderlichen Sammlungsklasse eine bewährte Programmiermethode.
Hinweis: Jede Implementierung der unveränderlichen Guava-Sammlungsklassen lehnt Nullwerte ab. Wir haben den internen Code von Google umfassend untersucht und festgestellt, dass Sammlungsklassen nur in 5 % der Fälle Nullwerte zulassen, während sie in 95 % der Fälle Nullwerte ablehnen. Falls Sie wirklich eine Sammlungsklasse benötigen, die Nullwerte akzeptieren kann, können Sie die Verwendung von Collections.unmodifiableXXX in Betracht ziehen.
So verwenden Sie unveränderliche Sammlungen:
Eine unveränderliche Sammlung kann auf folgende Weise erstellt werden:
1. Verwenden Sie die copyOf-Methode, zum Beispiel ImmutableSet.copyOf(set )
2. Verwenden Sie die of-Methode, zum Beispiel ImmutableSet.of("a", "b", "c") oder ImmutableMap.of("a", 1, "b", 2)
3. Verwenden Sie die Builder-Klasse
[code]@Test public void testGuavaImmutable(){ List<String> list=new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); System.out.println("list:"+list); ImmutableList<String> imlist=ImmutableList.copyOf(list); System.out.println("imlist:"+imlist); ImmutableList<String> imOflist=ImmutableList.of("peida","jerry","harry"); System.out.println("imOflist:"+imOflist); ImmutableSortedSet<String> imSortList=ImmutableSortedSet.of("a", "b", "c", "a", "d", "b"); System.out.println("imSortList:"+imSortList); list.add("baby"); System.out.println("list add a item after list:"+list); System.out.println("list add a item after imlist:"+imlist); ImmutableSet<Color> imColorSet = ImmutableSet.<Color>builder() .add(new Color(0, 255, 255)) .add(new Color(0, 191, 255)) .build(); System.out.println("imColorSet:"+imColorSet); }
„b“, „c“, „a“, „d“, „b“). Die Durchlaufreihenfolge dieser Sammlung lautet „ a“, „b“, „c“, „d“.
Intelligenteres copyOf
Die copyOf-Methode ist intelligenter als Sie denken. Unter bestimmten Umständen vermeidet ImmutableXXX.copyOf das Kopieren von Elementen. Ignorieren Sie zunächst die spezifischen Details, aber ihre Implementierung ist im Allgemeinen sehr „intelligent“. . Beispiel:
[code]@Test public void testCotyOf(){ ImmutableSet<String> imSet=ImmutableSet.of("peida","jerry","harry","lisa"); System.out.println("imSet:"+imSet); ImmutableList<String> imlist=ImmutableList.copyOf(imSet); System.out.println("imlist:"+imlist); ImmutableSortedSet<String> imSortSet=ImmutableSortedSet.copyOf(imSet); System.out.println("imSortSet:"+imSortSet); List<String> list=new ArrayList<String>(); for(int i=0;i<20;i++){ list.add(i+"x"); } System.out.println("list:"+list); ImmutableList<String> imInfolist=ImmutableList.copyOf(list.subList(2, 18)); System.out.println("imInfolist:"+imInfolist); int imInfolistSize=imInfolist.size(); System.out.println("imInfolistSize:"+imInfolistSize); ImmutableSet<String> imInfoSet=ImmutableSet.copyOf(imInfolist.subList(2, imInfolistSize-3)); System.out.println("imInfoSet:"+imInfoSet); }
[code]imSet:[peida, jerry, harry, lisa] imlist:[peida, jerry, harry, lisa] imSortSet:[harry, jerry, lisa, peida] list:[0x, 1x, 2x, 3x, 4x, 5x, 6x, 7x, 8x, 9x, 10x, 11x, 12x, 13x, 14x, 15x, 16x, 17x, 18x, 19x] imInfolist:[2x, 3x, 4x, 5x, 6x, 7x, 8x, 9x, 10x, 11x, 12x, 13x, 14x, 15x, 16x, 17x] imInfolistSize:16 imInfoSet:[4x, 5x, 6x, 7x, 8x, 9x, 10x, 11x, 12x, 13x, 14x]
In diesem Code gibt ImmutableList.copyOf(imSet) auf intelligente Weise imSet.asList() von ImmutableSet mit konstanter Zeitkomplexität zurück.
Im Allgemeinen vermeidet ImmutableXXX.copyOf(ImmutableCollection) Kopiervorgänge mit linearer Komplexität. Zum Beispiel in der folgenden Situation:
Diese Operation kann die Konstantkomplexitätsoperation der gekapselten Datenstruktur nutzen. Aber zum Beispiel kann ImmutableSet.copyOf(list) nicht mit konstanter Komplexität implementiert werden.
Dies führt nicht zu Speicherverlusten – Sie haben beispielsweise eine ImmutableList imInfolist und führen dann explizit ImmutableList.copyOf(imInfolist.subList(0, 10)) aus. Dieser Vorgang verhindert, dass versehentlich Verweise auf Elemente in der HugeList gespeichert werden, die nicht mehr benötigt werden.
Die Semantik des Satzes wird dadurch nicht geändert – explizite Kopiervorgänge wie ImmutableSet.copyOf(myImmutableSortedSet), da sich die Bedeutung von hashCode() und equal() in ImmutableSet von der komparatorbasierten ImmutableSortedSet unterscheidet.
Diese Funktionen tragen dazu bei, den Leistungsaufwand der defensiven Programmierung zu optimieren.
asList-Methode
Alle unveränderlichen Sammlungen bieten ImmutableList-Ansichten in Form von asList(). Wenn Sie die Daten beispielsweise in ImmutableSortedSet ablegen, können Sie sortedSet.asList().get(k) aufrufen, um die Menge der ersten k Elemente abzurufen.
Die zurückgegebene ImmutableList ist häufig eine Ansicht mit konstanter Komplexität und keine echte Kopie. Mit anderen Worten: Diese zurückgegebene Sammlung ist intelligenter als eine normale Liste – sie implementiert beispielsweise Methoden wie „Contains“ effizienter.
[code] @Test public void testAsList(){ ImmutableList<String> imList=ImmutableList.of("peida","jerry","harry","lisa","jerry"); System.out.println("imList:"+imList); ImmutableSortedSet<String> imSortList=ImmutableSortedSet.copyOf(imList); System.out.println("imSortList:"+imSortList); System.out.println("imSortList as list:"+imSortList.asList()); }
[code]imList:[peida, jerry, harry, lisa, jerry] imSortList:[harry, jerry, lisa, peida] imSortList as list:[harry, jerry, lisa, peida]
Guava集合和不可变对应关系
可变集合类型 可变集合源:JDK or Guava? Guava不可变集合
Collection JDK ImmutableCollection
List JDK ImmutableList
Set JDK ImmutableSet
SortedSet/NavigableSet JDK ImmutableSortedSet
Map JDK ImmutableMap
SortedMap JDK ImmutableSortedMap
Multiset Guava ImmutableMultiset
SortedMultiset Guava ImmutableSortedMultiset
Multimap Guava ImmutableMultimap
ListMultimap Guava ImmutableListMultimap
SetMultimap Guava ImmutableSetMultimap
BiMap Guava ImmutableBiMap
ClassToInstanceMap Guava ImmutableClassToInstanceMap
Table Guava ImmutableTable
以上就是Java-类库-Guava-Immutable(不可变)集合的内容,更多相关内容请关注PHP中文网(www.php.cn)!