1.基本工具[Basic utilities]
让使用Java语言变得更舒适
1.1使用和避免null Optional
获取Optional实例的几种方法
①Optional.of(T):获取一个Optional对象,其内部包含了一个非null的T数据类型实例,若T=null,则在运行时抛出异常。
②Optional.absent():获得一个Optional对象,其内部包含了null(即空值)。
③Optional.fromNullable(T): 将一个T的实例转换为Optional对象,T的实例可以不为空,也可以为空;即Optional.fromNullable(null)和Optional.absent()时等价的。
用Optional实例查询引用(以下都是非静态方法):
boolean isPresent() 如果Optional包含非null的引用(引用存在),返回true
T get() 返回Optional所包含的引用,若引用缺失,则抛出java.lang.lllegalStateException
T or(T) 返回Optional所包含的引用,若引用缺失,返回指定的值
T orNull() 返回Optional所包含的引用,若引用缺失,返回null
Set<T> asSet() 返回Optional所包含引用的单例不可变集,如果引用存在,返回一个只有单一元素的集合(1),如果引用缺失,返回一个空集合(0)
当你需要用一个默认值来替换可能的null,请使用Objects.firsNonNull(T,T)方法。
如果两个值都是null,该方法会抛出NullPointerException。Optional也是一个比较好的替换方案,例如:Optional.fromNullable(first).or(second)
1.2 前置条件:让方法中的条件检查更简单
checkNotNull(T) 检查vlaue不为null,直接返回value
失败时抛出的异常类型:NullPoniterException
checkArgument(boolean) 检查boolean是否为true,用来检查传递给方法的参数
失败时抛出的异常类型:lllegalArgumentExeption
1.3 常见Object方法:简化Object方法实现,如hashCode()和toString()
equals
Objects.equal 执行null敏感的equals判断,从而避免抛出NullPoniterException
hashcode
计算对象的hash值我们在日常编程中经常需要进行的操作,因为大量使用了对象容器类如Map、Set等,这些对象容器类判断对象冲突需要依赖对象的hash值。
Guava的Objects.hashCode(Object…):int 提供计算对象hash值得一般方法。
toString
toString方法帮组我们更加详细得打印内部信息
compareTo
ComparisonChain实现的compare和compareTo在代码可读性和性能上都有很大得提高、
1.4 排序:Guava强大的“流程风格比较器”
多列进行排序 这里可以使用到Guava的ComparisonChain,ComparisionChain是一个链式排序逻辑,把需要排序的列先后往ComparisonChain中添加即可,主要的代码
一、创建排序器
本质上来说,Ordering 实例无非就是一个特殊的Comparator 实例。
Ordering把很多基于Comparator的静态方法(如Collections.max)包装为自己的实例方法(非静态方法),
并且提供了链式调用方法,来定制和增强现有的比较器
1.5 Throwables:简化了异常和错误的传播与检查
2.集合[Collections]
Guava对JDK集合的拓展,这是Guava最成熟和为人所知的部分
2.1不可变集合:用不可变的集合进行防御性编程和性能提升。
不可变集合可以用如下多种方式创建:
copyOf方法,如ImmutableSet.copyOf();
of方法,如ImmutableSet.of(“a”,”b”,”c”)或ImmutableMap.of(“a”,1,”b”,2)
Builder工具,如
2.2 新集合类型:multisets,multimaps,tables,bidrectional map
Multiset
可以保存多个相同对象 允许重复,但是不保证顺序 通常用来统计元素出现的次数
Guava提供了多种Multiset的实现,大致对应JDK种的Map的各种实现:
SortedMultiset
SortedMultiset支持高效的获取指定范围的子集
需要注意,SortedMultiset默认是排好序的,是按元素来进行排序的而不是元素的个数
Multimap
在很多时候我们需要一个key对应多个值,Guava为我们提供了Multimap,可以用来做一个Key映射多个值的操作
Multimap的各种实现
BiMap
Guava提供了BiMap,它是一种特殊的Map,可以实现键值的反转
可以看出,因为BiMap要支持反转,所以它的key和value都必须是唯一的,要不翻转过来就存在一对多情况
Table
需要做key映射key_value时,实现一个表格的行、列、值得结构,Guava提供了表格来解决这种场景
Table支持row、column、value 我们把上面定义的map结构想象成一张数据表就可以了:
Table<R,C,V> == Map<R,Map<C,V>>
2.3 强大的集合工具类:提供java.util.Collections中没有的集合工具
2.4扩展工具类:让实现和扩展集合类变得更容易,比如创建Collection的装饰器,或实现迭代器
一、ForwardingList装饰器
二、PeekingIterator
三、Abstractlterator
3.缓存[Caches]
Guava Cache:本地缓存实现,支持多种缓存过期策略
4.函数式风格[Functional idioms]
5.并发[Concurrency]
强大而简单的抽象,让编写正确的并发代码更简单
5.1 ListenableFuture 完成后触发回调的Future
Guava提供的通用公共类封装了公共的操作方法,不需要提供Future和ListenableFuture的扩展方法。
ListenableFuture可以允许你注册回调方法(Callbacks),在运算(多线程执行)完成的时候进行调用,或者在运算(多线程执行)玩抽立即执行。
ListenableFuture中的基础方法时addListener(Runnable,Executor)该方法会在多线程运算玩的时候,指定Runnable参数传入的对象会被指定的Executor执行。
添加回调(Callbacks):
A FutureCallback<V>实现两种方法:
onSuccess(v) 在Future执行成功时去执行,取得成功结果
onFailure(Throwable),在Future执行失败时去执行失败,取得失败的结果
java future
执行结果:
Guava future
(减少主函数的等待时间,使得多任务能够异步非阻塞执行)
执行结果:
实际的使用中建议使用Guava ListenableFuture来实现异步非阻塞,目的就是多任务异步执行,通过回调的方式来获取执行结果而不需轮询任务状态。
5.2 Service框架:抽象可开启和关闭的服务,帮助你维护服务的状态逻辑
Guava包里的Service框架可以帮助我们把异步操作封装成一个Service服务。让这个服务有了运行状态(我们也可以理解成生命周期),这样我们可以实时了解当前服务的运行状态。同时我们还可以添加监听器来监听服务运行状态之间的变化。
Guava 里面的服务有五种状态,如下所示:
Service.State.NEW: 服务创建状态
Service.State.STARTING: 服务启动中
Service.State.RUNNING: 服务启动完成,正在运行中
Service.State.STOPPING: 服务停止中
Service.State.TERMINATED: 服务停止完成,结束
Guava提供了三个基础实现类 :AbstractService,AbstractExecutionThreadService,AbstractScheduledService
AbstractExecutionThreadService
AbstractExecutionThreadService可以帮助我们把一个具体的异步操作封装成Service服务,把之前在现场的实现逻辑封装成服务,
把之前线程的具体实现逻辑搬到AbstractExecutionThreadService的实现方法run()方法去执行。
常用方法:
开始执行我们服务逻辑的时候会调用,我们可以在里面做一些初始化操作
protected void startUp() throws Exception;
我们当前服务需要执行的具体逻辑
protected abstract void run() throw Exception;
服务停止之后会调用的函数,我们能可以在里面做一些释放资源的处理
protected void shutDown() throws Exception{}
比如在我们run方法里面有一个无线循环,可以在这个方法里面重置状态,推出无限循环,让服务真正停止
调stopAsync函数的时候,会调用该方法
protected void triggerShutdown(){}
使用
如何把线程的操作的具体逻辑搬到AbstractExecutionThreadServiceImpl里面去做。
进行测试
AbstractScheduledService
AbstractScheduledService可以把周期性的任务封装成一个服务。
常用方法
周期任务的具体逻辑在这里实现
protected abstract void runOneIteration() throws Exception;
启动周期任务之前调用,我们可以在里面做一些初始化的操作
protected void startUp() throws Exception;
周期任务停止之后调用,可以做一些释放资源的处理
protected void shutDown() throws Exception {}
指定当前周期任务在哪个ScheduledExecutorService里调用Scheduler.newFixedDelaySchedule()
protected abstract Scheduler scheduler();
使用
ServiceManager
ServiceManager是用来管理多个服务的,让对多个服务进行操作更加容易,比如同时启动多个服务,同时停止多个服务。
常用方法
构造函数,管理多个Service服务
public ServiceManager(Iterable<? Extends Service> services);
给ServiceManager增加状态监听器
public void addListener(Listener listener, Executor executor);
public void addListener(Listener listener);
开机启动ServiceManager里面所有Service服务
Public ServiceManager startAsync();
等待ServiceManager里面所有Service服务达到终止状态
public void awaitStopped();
public void awaitStopped(long timeout, TimeUnit unit) throws TimeoutException;
ServiceManager里面所有Service服务是否都达到了Running状态
public boolean isHealthy();
以状态为索引返回当前所有服务的快照
public ImmutableMultimap<State, Service> servicesByState();
返回一个Map对象,记录被管理的服务启动的耗时、以毫秒为单位,同时Map默认按启动时间排序
public ImmutableMap<Service,Long> startupTimes();
使用
6.字符串处理[Strings]
一、Joiner
根据给定的分隔符把字符串连接到一起
二、Splitter
主要功能是拆分字符串为集合Map等。通过分析源码可知,该工具类是通过on函数传入拆分字符得到实例。
三、Strings
7.原生类型[Primitives]
8.区间[Ranges]
9.I/O
10.散列[Hash]