- By刘立博
- 2021-06-21 20:48:01
- 912人已阅读
通过Optional特性避免Null
大多数情况下,使用null表明的是某种缺失的情况.Guava引入Optional<T>表明可能为null的T类型引用,Optional实例可能包含非null引用(引用存在),也可能什么也不包括(引用缺失),正是受到Guava启发,Java8将Optional类做为一个新特性引入进Java8的类库.
创建Optional
//创建空Optional对象
Optional<Object> empty = Optional.empty();
//使用任意值创建Optional对象
Optional<String> aaa = Optional.ofNullable("value");
//使用非空值创建Optional对象
Optional<String> bbb = Optional.of("aaa");
判断Optional对象引用是否缺失
empty.isPresent();
当Optional对象引用存在时执行
aaa.ifPresent(System.out::println);
当Optional对象引用缺失时执行
//返回一个对象
System.out.println(empty.orElse("empty 引用缺失1"));
//执行匿名函数
empty.orElseGet(()->{
System.out.println("empty 引用缺失2");
return "empty";
});
//抛出异常
try {
empty.orElseThrow(()-> new Exception("empty 引用缺失3"));
} catch (Exception e) {
System.out.println(e.getMessage());
}
不可变集合
创建对象的不可变拷贝是一项很好的防御性编程技巧
Guava为所有的JDK标准集合类型和Guava新集合类型都提供了简单易用的不可变版本
不可变对象的优点
当对象被不可信的库调用时,不可变形式是安全的
不可变对象被多个线程调用时,不存在竟态条件问题
不可变集合不需要考虑变化,因此可以节省时间和空间
不可变对象因为固定不变,可以作为常量来安全使用
JDK提供的方法
List<Integer> list = new ArrayList<>();
list.add(0);
list.add(1);
list.add(2);
//将可变列表转为不可变列表
List<Integer> integers = Collections.unmodifiableList(list);
Guava提供的方法
//通过已经存在的集合创建
ImmutableSet<Integer> copyList = ImmutableSet.copyOf(list);
//通过初始值创建
ImmutableSet<Integer> immutableSet = ImmutableSet.of(1,2,3);
//以builder方式创建
ImmutableSet<Object> build = ImmutableSet.builder().add(1).add(2).add(3).build();
新集合类型
Guava引入了很多JDK没有的、但明显有用的新集合类型,这些新类型是为了和JDK集合框架共存,而没有往JDK集合抽象中硬塞其他概念.
Multiset两种视角
(1)没有元素顺序限制的ArrayList<E>
Add(E) : 添加单个元素
Iterator(): 返回一个迭代器,包含Multiset所有元素(包括重复元素)
Size(): 返回所有元素总个数(包括重复元素)
(2)Map<E,Integer>,键为元素,值为计数
Count(Object): 返回给定元素计数
entrySet(): 返回Set<Multiset.Entry<E>>和Map的entrySet类似
elementSet():返回所有不重复元素的Set<E>和Map的keySet类似
Multiset和Map的区别
元素计数只能是正数
Multiset.size()返回集合大小
Multiset.iterator()会迭代重复元素
multiset支持直接设置元素的计数
没有元素,multiset.count(E)为0
一个栗子:Multiset实现文字计数
@Test
public void testMultiset()
{
String text =
"关关雎鸠,在河之洲。窈窕淑女,君子好逑。" +
"参差荇菜,左右流之。窈窕淑女,寤寐求之。" +
"求之不得,寤寐思服。悠哉悠哉,辗转反侧。" +
"参差荇菜,左右采之。窈窕淑女,琴瑟友之。" +
"参差荇菜,左右芼之。窈窕淑女,钟鼓乐之。";
HashMultiset<Character> result = HashMultiset.create();
char[] chars = text.toCharArray();
result.addAll(Chars.asList(chars));
Set<Multiset.Entry<Character>> entries = result.entrySet();
for (Multiset.Entry<Character> entry : entries) {
System.out.println(entry.getElement()+"--"+result.count(entry.getElement()));
}
System.out.println("size:"+result.size());
}
流--1
。--10
参--3
求--2
荇--3
采--1
窈--4
...
size:100
集合工具类
Guava为集合提供了许多工具方法,这也是Guava最流行和成熟的部分之一,常见集合工具类如:Lists、Sets、Maps等
使用Lists工具类操作List集合
//分组
@Test
public void partition()
{
ArrayList<Integer> integers = Lists.newArrayList(1, 2, 3, 4, 5, 6);
List<List<Integer>> partition = Lists.partition(integers, 3);
System.out.println(partition);
}
//反转
@Test
public void reverse()
{
LinkedList<Integer> list = Lists.newLinkedList();
list.add(1);
list.add(2);
list.add(3);
List<Integer> reverse = Lists.reverse(list);
System.out.println(reverse);
}
使用Sets工具类操作Set集合
private static final Set set1 = Sets.newHashSet(1,2);
private static final Set set2 = Sets.newHashSet(2,3,4);
//并集
@Test
public void testSets()
{
Set<Integer> union = Sets.union(set1, set2);
System.out.println(union);
}
//交集
@Test
public void intersection()
{
Set<Integer> intersection = Sets.intersection(set1, set2);
System.out.println(intersection);
}
//差集
@Test
public void difference()
{
Set<Integer> intersection = Sets.difference(set1,set2);
System.out.println(intersection);
}
//拆分
@Test
public void powerSet()
{
Set<Set<Integer>> set = Sets.powerSet(set1);
System.out.println(JSON.toJSONString(set));
}
I/O操作
对字节流和字符流提供的工具方法
ByteStreams:提供对InputStream、OutputStream的操作
CharStreams:提供对Reader、Writer的操作
对源(source)和汇(sink)的抽象
源是可读的:ByteSource、CharSource
汇是可写的:ByteSink、CharSink
一个栗子:复制文件
@Test
public void ioTest() throws IOException
{
CharSource charSource = Files.asCharSource(new File("source.txt"), Charsets.UTF_8);
CharSink charSink = Files.asCharSink(new File("target.txt"), Charsets.UTF_8);
charSource.copyTo(charSink);
}