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