Maison >Java >javaDidacticiel >Collection Java-Class Library-Guava-Immutable (immuable)

Collection Java-Class Library-Guava-Immutable (immuable)

黄舟
黄舟original
2017-01-19 13:24:201578parcourir

Collection immuable, comme son nom l'indique, signifie que la collection ne peut pas être modifiée. Les données d'une collection sont fournies au moment de la création et ne peuvent être modifiées tout au long du cycle de vie.

Pourquoi utiliser des objets immuables ? Les objets immuables présentent les avantages suivants :

1. Ils peuvent être utilisés en toute sécurité pour des bibliothèques de code client peu fiables, et ces objets peuvent être utilisés en toute sécurité dans des bibliothèques de classes non fiables

2 .Thread-safe : immuable les objets sont en sécurité dans plusieurs threads et n'ont aucune condition de concurrence

  3. Il n'est pas nécessaire de prendre en charge la mutabilité et vous pouvez essayer d'économiser de l'espace et du temps. Toutes les implémentations de collections immuables sont meilleures que les collections mutables utilisées par les collections. mémoire plus efficacement (analyse)

4. Peut être utilisé comme constante et devrait rester inchangé à l'avenir

Les objets immuables peuvent être utilisés comme constantes naturellement, car ils sont intrinsèquement immuables . C'est une bonne technique de programmation défensive que d'utiliser des objets immuables.

Implémentation de collections immuables dans le JDK

Une série de méthodes Collections.unmodifiableXXX est fournie dans le JDK pour implémenter des collections immuables, mais il y a quelques problèmes ci-dessous :

[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. C'est maladroit et fastidieux à utiliser et vous devez utiliser cette méthode dans chaque copie de programmation défensive

2. C'est dangereux : Si s'il existe un objet qui fait référence à la classe de collection encapsulée d'origine, les collections renvoyées par ces méthodes ne sont pas vraiment immuables.

3. Faible efficacité : étant donné que l'essence de la structure de données renvoyée est toujours la classe de collection d'origine, sa surcharge de fonctionnement, y compris la vérification des modifications simultanées, et l'espace de données supplémentaire dans la table de hachage sont les mêmes que ceux de la classe de collecte d'origine. collection originale Idem.

Collection immuable de Guava

Guava fournit une implémentation simple et pratique de la version immuable de la classe de collection standard dans le JDK, ainsi que la propre implémentation immuable de Guava de certaines classes de collection spécialisées. Lorsque vous ne souhaitez pas modifier une classe de collection ou créer une classe de collection constante, l'utilisation d'une classe de collection immuable est une bonne pratique de programmation.

Remarque : Chaque implémentation de classes de collection immuables Guava rejette les valeurs nulles. Nous avons mené une enquête approfondie sur le code interne de Google et avons constaté que les classes de collection autorisent les valeurs nulles dans seulement 5 % des cas, tout en rejetant les valeurs nulles dans 95 % des cas. Si vous avez vraiment besoin d'une classe de collection pouvant accepter des valeurs nulles, vous pouvez envisager d'utiliser Collections.unmodifiableXXX.

Comment utiliser les collections immuables :

Une collection immuable peut être créée des manières suivantes :

1. Utilisez la méthode copyOf, par exemple, ImmutableSet.copyOf(set )

 2. Utilisez la méthode of, par exemple, ImmutableSet.of("a", "b", "c") ou ImmutableMap.of("a", 1, "b", 2)

 3. Utilisez la classe Builder

[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"), l'ordre de parcours de cette collection est " a", "b", "c", "d".

CopieOf plus intelligente

La méthode copyOf est plus intelligente que vous ne le pensez. ImmutableXXX.copyOf évitera de copier des éléments dans des circonstances appropriées - ignorez d'abord les détails spécifiques, mais sa mise en œuvre est généralement très "intelligente". . Par exemple,

[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]



Dans ce code, ImmutableList.copyOf(imSet) renverra intelligemment imSet.asList() de ImmutableSet avec une complexité temporelle constante.

De manière générale, ImmutableXXX.copyOf(ImmutableCollection) évitera les opérations de copie de complexité linéaire. Par exemple, dans la situation suivante :

Cette opération peut tirer parti de la complexité constante du fonctionnement de la structure de données encapsulée. Mais par exemple, ImmutableSet.copyOf(list) ne peut pas être implémenté avec une complexité constante.

Cela ne provoquera pas de fuites de mémoire - par exemple, vous avez un ImmutableList imInfolist, puis vous utilisez explicitement ImmutableList.copyOf(imInfolist.subList(0, 10)). Cette opération évite de conserver accidentellement des références à des éléments de la hugeList qui ne sont plus nécessaires.

Cela ne changera pas la sémantique de l'ensemble - opérations de copie explicites comme ImmutableSet.copyOf(myImmutableSortedSet), car la signification de hashCode() et equals() dans ImmutableSet est différente de celle basée sur un comparateur ImmutableSortedSet .

Ces fonctionnalités permettent d'optimiser les performances de la programmation défensive.

Méthode asList

Toutes les collections immuables fournissent des vues ImmutableList sous la forme de asList(). Par exemple, si vous placez les données dans ImmutableSortedSet, vous pouvez appeler sortedSet.asList().get(k) pour obtenir l'ensemble des k premiers éléments.

L'ImmutableList renvoyée est souvent une vue à complexité constante plutôt qu'une copie fidèle. En d’autres termes, cette collection renvoyée est plus intelligente qu’une liste normale – par exemple, elle implémentera plus efficacement des méthodes telles que contain.

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


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn