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 |