Google-Guava学习:不可变集合

时间:2021-02-23 20:47:37

不可变对象有很多优点,包括:

  • 当对象被不可信的库调用时,不可变形式是安全的;
  • 不可变对象被多个线程调用时,不存在竞态条件问题
  • 不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节);
  • 不可变对象因为有固定不变,可以作为常量来安全使用。

JDK也提供了Collections.unmodifiableXXX方法把集合包装为不可变形式,但我们认为不够好:

  • 笨重而且累赘:不能舒适地用在所有想做防御性拷贝的场景;
  • 不安全:要保证没人通过原集合的引用进行修改,返回的集合才是事实上不可变的;
  • 低效:包装过的集合仍然保有可变集合的开销,比如并发修改的检查、散列表的额外空间,等等。

示例如下(ImmutableSet):

package com.cyq.test;

import java.awt.Color;
import java.util.Arrays;
import java.util.List;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.UnmodifiableIterator;

/**
* @author cyq
*
*/

public class ImmutableSetTest {

public ImmutableSetTest() {
//构造方法一: copyOf方法
List<String> list=Arrays.asList("1","3","2");
ImmutableSet<String> immutableSet1 = ImmutableSet.copyOf(list);
immutableSet1.forEach(System.out::println);
System.out.println("-----------------------");
//构造方法二: of方法
ImmutableSet<String> immutableSet2 = ImmutableSet.of("a", "c", "b");
immutableSet2.forEach(System.out::println);
System.out.println("-----------------------");
//构造方法三: Builder工具
ImmutableSet<Color> immutableSet3 = ImmutableSet.<Color>builder()
.add(new Color(0, 191, 255))
.add(new Color(12, 191, 255))
.add(new Color(14, 191, 255))
.build();
immutableSet3.forEach(System.out::println);
System.out.println("-----------------------");

//此外,对有序不可变集合来说,排序是在构造集合的时候完成的,如:
ImmutableSortedSet<String> sortedSet = ImmutableSortedSet.of("a", "c", "b", "a", "d", "b");
UnmodifiableIterator<String> iterator = sortedSet.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());//a, b, c, d
}
}

public static void main(String[] args) {

new ImmutableSetTest();
}
}

关联可变集合和不可变集合:

可变集合接口 属于JDK还是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