让使用 Java 语言变得更舒适
本文主要通过例子的方式简单介绍了一下基本工具的使用。
如果希望了解更多的细节,可以可以查看目录中的链接进行查看。
— By Syahfozy
1 使用和避免 null:null 是模棱两可的,会引起令人困惑的错误,有些时候它让人很不舒服。很多 Guava 工具类用快速失败拒绝 null 值,而不是盲目地接受
2 前置条件: 让方法中的条件检查更简单
3 常见 Object 方法: 简化 Object 方法实现,如 hashCode() 和 toString()
4 排序: Guava 强大的” 流畅风格比较器”
5 Throwables:简化了异常和错误的传播与检查
一、使用和避免null
很多 Guava 工具类用快速失败拒绝 null 值,而不是盲目地接受
大多数情况下,开发人员使用null表明的是某种缺失情形:可能是已经有一个默认值,或没有值,或找不到值。例如,Map.get返回null就表示找不到给定键对应的值
Guava用Optional表示可能为null的T类型引用。一个Optional实例可能包含非null的引用(我们称之为引用存在),也可能什么也不包括(称之为引用缺失)。它从不说包含的是null值,而是用存在或缺失来表示。但Optional从不会包含null值引用
1. 创建Optional实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
public void makingAnOptional() {
Optional<Integer> possible = Optional.of(5);
possible = Optional.absent();
possible = Optional.fromNullable(5); possible = Optional.fromNullable(null); }
|
2. 创建Optional实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
public void queryMethods() { Optional<Integer> possible = Optional.of(5); possible.isPresent();
possible.get();
possible.or(3);
possible.orNull();
possible.asSet(); }
|
3. 其他处理null的便利方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
public void convenienceMethods() {
MoreObjects.firstNonNull(5, 6); Optional.fromNullable(null).or(6);
emptyToNull("");
isNullOrEmpty(""); isNullOrEmpty(null);
nullToEmpty(null); nullToEmpty("hello"); }
|
二、前置条件:让方法调用的前置条件判断更简单
Guava在Preconditions类中提供了若干前置条件判断的实用方法,每个方法都有三个变种:
- 没有额外参数:抛出的异常中没有错误消息;
- 有一个Object对象作为额外参数:抛出的异常使用Object.toString() 作为错误消息;
- 有一个String对象作为额外参数,并且有一组任意数量的附加Object对象:这个变种处理异常消息的方式有点类似printf,但考虑GWT的兼容性和效率,只支持%s指示符
1. 使用示例
1 2 3 4 5 6 7 8
| checkArgument(i <= 0);
checkArgument(i <= 0, "Argument Exception");
checkArgument(i < j, "Expected i < j, but %s > %s", i, j);
|
2. 常用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
checkArgument(Boolean.TRUE);
checkNotNull(null);
checkState(Boolean.FALSE);
checkElementIndex(3,3);
checkPositionIndex(3, 3);
checkPositionIndexes(0, 3, 3);
|
三、常见Object方法
1. equals
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public static void equalsMethod() { Objects.equal("a", "a"); Objects.equal(null, "a"); Objects.equal("a", null); Objects.equal(null, null);
}
|
2. hashCode
1 2 3 4 5 6 7 8 9
|
public static void hashCodeMethod() { int hash = Objects.hashCode(2, "hello", null); System.out.println(hash); }
|
3. toString
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
public void toStringHelperMethod() {
String s1 = MoreObjects.toStringHelper(this) .add("x", 1) .toString(); System.out.println(s1);
String s2 = MoreObjects.toStringHelper("MyObject") .add("x", 1) .toString(); System.out.println(s2);
}
|
4. compare/compareTo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Person implements Comparable<Person> { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; }
public int compareTo(Person that) { return ComparisonChain.start() .compare(this.age, that.age) .compare(this.name, that.name) .result(); } } public void compare() { Person a = new Person("a", 10); Person b = new Person("a", 10); System.out.println(b.compareTo(a)); }
|
四、排序: Guava强大的”流畅风格比较器”
排序器[Ordering]是Guava流畅风格比较器[Comparator]的实现,它可以用来为构建复杂的比较器,以完成集合排序的功能
从实现上说,Ordering实例就是一个特殊的Comparator实例。Ordering把很多基于Comparator的静态方法(如Collections.max)包装为自己的实例方法(非静态方法),并且提供了链式调用方法,来定制和增强现有的比较器
1. 创建排序器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
public static void creationMethod(){
Ordering<String> naturalOrdering = natural(); Ordering<Object> usingToStringOrdering = usingToString(); Ordering<String> fromOrdering = Ordering.from(new Comparator<String>() { public int compare(String o1, String o2) { return o1.hashCode() - o2.hashCode() ; } }); Ordering<String> byLengthOrdering = new Ordering<String>() { public int compare(String left, String right) { return Ints.compare(left.length(), right.length()); } }; }
|
2. 链式调用方法
通过链式调用,可以由给定的排序器衍生出其它排序器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
public static void chainingMethod(){
List<String> withNullList = Lists.newArrayList(list); withNullList.add(null); System.out.println("withNullList:"+ withNullList); List<List> listList = Lists.newArrayList(); listList.add(Lists.newArrayList("perter", "jerry")); listList.add(Lists.newArrayList("perter")); listList.add(Lists.newArrayList("perter", "jerry", null)); System.out.println("listList:"+ withNullList); Ordering<String> naturalOrdering = natural(); Ordering<String> reverseOrdering = natural().reverse(); Ordering<String> nullsFirst = natural().nullsFirst(); Ordering<String> nullsLast = natural().nullsLast(); Ordering<People> secondaryOrdering = new PeopleAgeOrder().compound(new PeopleNameLengthOrder()); Ordering lexicographicalOrdering = naturalOrdering.lexicographical(); Ordering<String> resultOfOrdering = natural().nullsFirst().onResultOf(new Function<String, Integer>() { public Integer apply(String input) { return input == null ? null : input.length(); } }); }
|
3. 运用排序器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
public static void applicationMethod() {
System.out.println("greatestOfOrdering:"+ natural().greatestOf(list, 3)); System.out.println("leastOfOrdering:"+ natural().leastOf(list, 3));
System.out.println("isOrdered:"+ natural().isOrdered(natural().sortedCopy(list))); System.out.println("isStrictlyOrdered:"+ natural().isStrictlyOrdered(natural().sortedCopy(list)));
System.out.println("isOrdered:"+ natural().sortedCopy(list)); natural().immutableSortedCopy(list);
System.out.println("min:" + natural().min("abc", "ab")); System.out.println("max:" + natural().max("abc", "ab"));
System.out.println("min:" + natural().min("ab", "cd", "abc")); System.out.println("max:" + natural().max("ab", "cde", "abc"));
System.out.println("min:" + natural().min(list)); System.out.println("max:" + natural().max(list));
}
|
五、Throwables:简化异常和错误的传播与检查
1. 异常传播方法
Guava中的异常传播方法简要列举如下:
1 2 3 4 5
| Throwables.throwIfInstanceOf(t, SQLException.class);
Throwables.throwIfUnchecked(t);
|
2. 异常原因链
Guava提供了如下三个有用的方法,让研究异常的原因链变得稍微简便了,这三个方法的签名是不言自明的:
1 2 3 4
| Throwable throwable = Throwables.getRootCause(t); List<Throwable> throwables = Throwables.getCausalChain(t); String str = Throwables.getStackTraceAsString(t);
|