Google Guava新手教程
以下资料整理自网络
一、Google Guava入门介绍
引言
Guavaproject包括了若干被Google的 Java项目广泛依赖 的核心库,比如:集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、并发库 [concurrency libraries] 、通用注解 [common annotations] 、字符串处理 [string processing] 、I/O 等等。 全部这些工具每天都在被Google的project师应用在产品服务中。
查阅Javadoc并不一定是学习这些库最有效的方式。在此,我们希望通过此文档为Guava中最流行和最强大的功能。提供更具可读性和解释性的说明。
译文格式说明
- Guava中的类被首次引用时,都会链接到Guava的API文档。如:Optional<T>。
- Guava和JDK中的方法被引用时。一般都会链接到Guava或JDK的API文档,一些人所共知的JDK方法除外。如:Optional.of(T), Map.get(key)。
- 译者对文档的额外说明以斜体显示,而且以“译者注:”開始。
文件夹
1. 基本工具 [Basic utilities]
让使用Java语言变得更舒适
1.1 使用和避免null:null是模棱两可的,会引起令人困惑的错误。有些时候它让人非常不舒服。
非常多Guava工具类用高速失败拒绝null值,而不是盲目地接受
1.2 前置条件: 让方法中的条件检查更简单
1.3 常见Object方法: 简化Object方法实现。如hashCode()和toString()
1.5 Throwables:简化了异常和错误的传播与检查
2. 集合[Collections]
Guava对JDK集合的扩展,这是Guava最成熟和为人所知的部分
2.1 不可变集合: 用不变的集合进行防御性编程和性能提升。
2.2 新集合类型: multisets, multimaps, tables, bidirectional maps等
2.3 强大的集合工具类: 提供java.util.Collections中没有的集合工具
2.4 扩展工具类:让实现和扩展集合类变得更easy。比方创建Collection的装饰器,或实现迭代器
3. 缓存[Caches]
Guava Cache:本地缓存实现,支持多种缓存过期策略
4. 函数式风格[Functional idioms]
Guava的函数式支持能够显著简化代码。但请慎重使用它
5. 并发[Concurrency]
强大而简单的抽象,让编写正确的并发代码更简单
5.1 ListenableFuture:完毕后触发回调的Future
5.2 Service框架:抽象可开启和关闭的服务,帮助你维护服务的状态逻辑
6. 字符串处理[Strings]
非常实用的字符串工具。包括切割、连接、填充等操作
7. 原生类型[Primitives]
扩展 JDK 未提供的原生类型(如int、char)操作, 包括某些类型的无符号形式
8. 区间[Ranges]
可比較类型的区间API。包括连续和离散类型
9. I/O
简化I/O尤其是I/O流和文件的操作,针对Java5和6版本号
10. 散列[Hash]
提供比Object.hashCode()更复杂的散列实现。并提供布鲁姆过滤器的实现
11. 事件总线[EventBus]
公布-订阅模式的组件通信,但组件不须要显式地注冊到其它组件中
12. 数学运算[Math]
优化的、充分測试的数学工具类
13. 反射[Reflection]
Guava 的 Java 反射机制工具类
中文參考站点:http://ifeve.com/google-guava/
二、Guava学习笔记:Preconditions优雅的检验參数
在日常开发中。我们常常会对方法的输入參数做一些数据格式上的验证,以便保证方法能够依照正常流程运行下去。对于可预知的一些数据上的错误。我们一定要做事前检測和推断,来避免程序流程出错,而不是全然通过错误处理来保证流程正确运行,毕竟错误处理是比較消耗资源的方式。
在寻常情况下我们对參数的推断都须要自己来逐个写方法推断,代码量不少而且复用性不高,例如以下所看到的:
import org.junit.Test; public class PreconditionsTest { @Test public void Preconditions() throws Exception { getPerson(8,"peida"); getPerson(-9,"peida"); getPerson(8,""); getPerson(8,null); } public static void getPerson(int age,String neme)throws Exception{ if(age>0&&neme!=null&&neme.isEmpty()!=true){ System.out.println("a person age:"+age+",neme:"+neme); }else{ System.out.println("參数输入有误。"); } } }
说明:參数验证。我们每次都要加入if语句来做推断, 反复的工作会做好多次。getPerson方法仅仅有2个參数。验证规则也不是非常复杂,假设參数过度,验证规则复杂后,上面代码的可读性都会非常差的,复用性就更谈不上了。
Guava类库中提供了一个作參数检查的工具类--Preconditions类, 该类能够大大地简化我们代码中对于參数的预推断和处理。让我们对方法输入參数的验证实现起来更加简单优雅。以下我们看看Preconditions类的使用实例:Preconditions里面的方法:
1 .checkArgument(boolean) :
功能描写叙述:检查boolean是否为真。 用作方法中检查參数
失败时抛出的异常类型: IllegalArgumentException
2.checkNotNull(T):
功能描写叙述:检查value不为null, 直接返回value;
失败时抛出的异常类型:NullPointerException
3.checkState(boolean):
功能描写叙述:检查对象的一些状态。不依赖方法參数。 比如, Iterator能够用来next是否在remove之前被调用。
失败时抛出的异常类型:IllegalStateException
4.checkElementIndex(int index, int size):
功能描写叙述:检查index是否为在一个长度为size的list, string或array合法的范围。 index的范围区间是[0, size)(包括0不包括size)。
无需直接传入list, string或array, 仅仅需传入大小。返回index。
失败时抛出的异常类型:IndexOutOfBoundsException
5.checkPositionIndex(int index, int size):
功能描写叙述:检查位置index是否为在一个长度为size的list。 string或array合法的范围。 index的范围区间是[0, size)(包括0不包括size)。无需直接传入list。 string或array, 仅仅需传入大小。返回index。
失败时抛出的异常类型:IndexOutOfBoundsException
6.checkPositionIndexes(int start, int end, int size):
功能描写叙述:检查[start, end)是一个长度为size的list。 string或array合法的范围子集。
伴随着错误信息。
失败时抛出的异常类型:IndexOutOfBoundsException
一个比較实用实例:
import java.util.ArrayList; import java.util.List; import org.junit.Test; import com.google.common.base.Preconditions; public class PreconditionsTest { @Test public void Preconditions() throws Exception { getPersonByPrecondition(8,"peida"); try { getPersonByPrecondition(-9,"peida"); } catch (Exception e) { System.out.println(e.getMessage()); } try { getPersonByPrecondition(8,""); } catch (Exception e) { System.out.println(e.getMessage()); } try { getPersonByPrecondition(8,null); } catch (Exception e) { System.out.println(e.getMessage()); } List<Integer> intList=new ArrayList<Integer> (); for(int i=0;i<10;i++){ try { checkState(intList,9); intList.add(i); } catch (Exception e) { System.out.println(e.getMessage()); } } try { checkPositionIndex(intList,3); } catch (Exception e) { System.out.println(e.getMessage()); } try { checkPositionIndex(intList,13); } catch (Exception e) { System.out.println(e.getMessage()); } try { checkPositionIndexes(intList,3,7); } catch (Exception e) { System.out.println(e.getMessage()); } try { checkPositionIndexes(intList,3,17); } catch (Exception e) { System.out.println(e.getMessage()); } try { checkPositionIndexes(intList,13,17); } catch (Exception e) { System.out.println(e.getMessage()); } try { checkElementIndex(intList,6); } catch (Exception e) { System.out.println(e.getMessage()); } try { checkElementIndex(intList,16); } catch (Exception e) { System.out.println(e.getMessage()); } } public static void getPersonByPrecondition(int age,String neme)throws Exception{ Preconditions.checkNotNull(neme, "neme为null"); Preconditions.checkArgument(neme.length()>0, "neme为\'\'"); Preconditions.checkArgument(age>0, "age 必须大于0"); System.out.println("a person age:"+age+",neme:"+neme); } public static void checkState(List<Integer> intList,int index)throws Exception{ //表达式为true不抛异常 Preconditions.checkState(intList.size()<index, " intList size 不能大于"+index); } public static void checkPositionIndex(List<Integer> intList,int index) throws Exception{ Preconditions.checkPositionIndex(index, intList.size(), "index "+index+" 不在 list中。 List size为:"+intList.size()); } public static void checkPositionIndexes(List<Integer> intList,int start,int end) throws Exception{ Preconditions.checkPositionIndexes(start, end, intList.size()); } public static void checkElementIndex(List<Integer> intList,int index) throws Exception{ Preconditions.checkElementIndex(index, intList.size(),"index 为 "+index+" 不在 list中, List size为: "+intList.size()); } }
输出结果:
a person age:8,neme:peida
age 必须大于0
neme为''
neme为null
intList size 不能大于9
index 13 不在 list中, List size为:9 (13) must not be greater than size (9)
end index (17) must not be greater than size (9)
start index (13) must not be greater than size (9)
index 为 16 不在 list中, List size为: 9 (16) must be less than size (9)
Guava的preconditions有这样几个长处:
在静态导入后, 方法非常明白无歧义, checkNotNull能够清楚地告诉你它是干什么的, 它会抛出如何的异常.
checkNotNull在验证通过后直接返回, 能够这样方便地写代码: this.field = checkNotNull(field).
简单而又强大的可变參数'printf'风格的自己定义错误信息.