WsztRush

让Guava来加速开发

在Java开发时,有很多事情比较繁琐:

  1. 判空
  2. 校验
  3. 集合处理
  4. 等等

比较简单的就是封装工具类,更简单呢,就是用现成的工具类,Guava(WIKI)就是这样一套工具,让你的代码“如丝般顺滑”。

基础

在代码中无处不再的NULL容易让人抓狂,处理的不好就来个NPE,而且处理的过程免不了加入一堆的if-else(丑丑的),此时Optional可以帮上忙:

Optional<Integer> optional = Optional.of(5);
System.out.println(optional.isPresent()); // true
System.out.println(optional.get());// 5
System.out.println(optional.or(123));// 5 (默认值是123)

Objects中也有处理NULL的方法:

Objects.firstNonNull(1, 2);// 1 // 返回第一个非空的,类似first.or(second);
Objects.equal(null, null); // true

排序时考虑多个字段比较麻烦,搞完的代码基本看不大懂,用ComparisonChain简化为:

static class Test {
    int a, b;
    Test(int a, int b) { this.a = a; this.b = b;}
}
public static void main(String[] args) throws Exception {
    Test t1 = new Test(1, 2), t2 = new Test(1, 3);
    System.out.println(ComparisonChain.start().compare(t1.a, t2.a).compare(t1.b, t2.b).result());// -1
}

有更多的排序逻辑时可以用Ordering。异常机制在向上传错误非常好用,但多了不少if-throw的代码,可以用Preconditions缩成一行:

Preconditions.checkState(false, "异常信息!"); // 第一个参数为false时抛异常

这些工具扩展了原生的不好用的地方,但其中很多在后续版本中已经完善了。

集合

原生的集合类用起来有时候不那么顺手,Guava封装了一些通用的复杂结构的实现。经常需要对数据做一些聚合,用原生的集合类有点繁琐,举个例子:

把批量查询的数据根据某个字段分组。

需要用Map<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>()来组织(过程中免不了判空等逻辑),类似情况可以用Multimap来减少工作量了:

Multimap<Integer, Integer> multimap = ArrayListMultimap.create();
multimap.put(1, 1);
multimap.put(1, 2);
multimap.put(1, 3);
System.out.println(multimap.get(1)); // [1, 2, 3]

而Multimap并不是一个Map(java.util.Map),但是用起来和Map差不多,而且需要时可以用asMap转换。根据值集合的不同需求有不同的实现(WIKI)。类似的工具还有Multiset

Multiset<Integer> multiset = HashMultiset.create();
multiset.add(1);
multiset.add(1);
multiset.add(1);
System.out.println(multiset.count(1)); // 3

一般情况都是key->value,用Map可以搞定,但如果同时需要value->key,此时可以用两个Map,也可以用一个BiMap

BiMap<String, Integer> userId = HashBiMap.create();
userId.put("a", 1);
userId.put("b", 2);
System.out.println(userId.inverse().get(2));// b

很多时候key是两个值拼起来的,可以用拼接成一个字符串,也可以用Table搞定(感觉有点浪费):

Table<String, String, Integer> table = HashBasedTable.create();
table.put("a", "b", 1);
table.put("a", "c", 2);
System.out.println(table.get("a", "b")); // 1
System.out.println(table.column("b")); // {a=1}
System.out.println(table.row("a")); // {b=1, c=2}

在Guava中还配套了一些集合相关的工具类,比如Maps(现在创建集合基本不用new了):

Map<Integer, Map<String, Integer>> map = Maps.newHashMap();

缓存