Heim  >  Artikel  >  Java  >  Java-Class Library-Guava-Immutable (unveränderliche) Sammlung

Java-Class Library-Guava-Immutable (unveränderliche) Sammlung

黄舟
黄舟Original
2017-01-19 13:24:201572Durchsuche

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)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn