JDK的Collections.unmodifiableXXX方法實現不可變集合的一些問題:java
1.它用起來笨拙繁瑣你不得不在每一個防護性編程拷貝的地方用這個方法
2.它不安全:若是有對象reference原始的被封裝的集合類,這些方法返回的集合也就不是正真的不可改變。
3.效率低:由於它返回的數據結構本質仍舊是原來的集合類,因此它的操做開銷,包括併發下修改檢查,hash table裏的額外數據空間都和原來的集合是同樣的。編程
Immutable集合使用方法:
一個immutable集合能夠有如下幾種方式來建立:
1.用copyOf方法, 譬如, ImmutableSet.copyOf(set)
2.使用of方法,譬如,ImmutableSet.of("a", "b", "c")或者ImmutableMap.of("a", 1, "b", 2)
3.使用Builder類安全
示例數據結構
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import org.junit.Test; import java.util.ArrayList; import java.util.List; /** * @author Kevin * @description * @date 2016/8/4 */ public class ImmutableTest { @Test public void testGuavaImmutable() { List<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); System.out.println("list:" + list); // 1.copy方式 ImmutableList<String> imlist = ImmutableList.copyOf(list); System.out.println("imlist:" + imlist); // 2.of方式 ImmutableList<String> imOflist = ImmutableList.of("Kevin", "Chris", "Han"); 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); // 3.builder方式 ImmutableSet<String> imColorSet = ImmutableSet.<String>builder() .add("Kevin") .add("Han") .build(); System.out.println("imColorSet:" + imColorSet); } @Test public void testCotyOf() { ImmutableSet<String> imSet = ImmutableSet.of("Kevin", "Chris", "Han", "Herry"); 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); } @Test public void testAsList() { ImmutableList<String> imList = ImmutableList.of("Kevin", "Chris", "Han", "Herry"); System.out.println("imList:" + imList); ImmutableSortedSet<String> imSortList = ImmutableSortedSet.copyOf(imList); System.out.println("imSortList:" + imSortList); System.out.println("imSortList as list:" + imSortList.asList()); } }
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 |