Guava 是 Google 的一个开源项目,包含许多 Google 核心 Java 常用库,如:集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、并发库 [concurrency libraries] 、通用注解 [common annotations] 、字符串处理 [string processing] 与 I/O 等。
常用的操作:
在google guava中为字符串操作提供了很大的便利,有老牌的判断字符串是否为空字符串或者为null,用指定字符填充字符串,以及拆分合并字符串,字符串匹配的判断等等。
1. 使用com.google.common.base.Strings类的isNullOrEmpty(input)方法判断字符串是否为空
boolean isNullOrEmpty = Strings.isNullOrEmpty(input);
2.Google Collections
1 | Map<String, Map<Long, List<String>>> map = new HashMap<String, Map<Long,List<String>>>(); |
要这么做:
1 | Map<String, Map<Long, List<String>>> map = Maps.newHashMap(); |
或者更甚者直接使用静态导入:
1 | Map<String, Map<Long, List<String>>>map = newHashMap(); |
类似于com.google.common.collect.Maps提供的这些静态工具方法,Lists和Sets也有:
1 | Lists.newArrayList(); |
2 | Sets.newHashSet(); |
3.对象操作封装
比较两个对象是否相等,这时候我们需要考虑比较的两个对象是否为null,然后再调用equals方法来比较是否相等,google guava库的com.google.common.base.Objects类提供了一个静态方法equals可以避免我们自己做是否为空的判断,示例如下:
Object a = null;
Object b = new Object();
boolean aEqualsB = Objects.equal(a, b);
Objects.equals源码:
public static boolean equal(@Nullable Object a, @Nullable Object b) {
return a == b || (a != null && a.equals(b));
}
首先判断a b是否是同一个对象,如果是同一对象,那么直接返回相等,如果不是同一对象再判断a不为null并且a.equals(b). 这样做既考虑了性能也考虑了null空指针的问题。
4.重写toString()方法
另外Objects类中还为我们提供了方便的重写toString()方法的机制:
public String toString() {
return Objects.toStringHelper(this.getClass())
.add("id", id)
.add("name", name)
.add("age", age)
.omitNullValues().toString();
}
我们定义了一个Student类,该类有三个属性,分别为id,name,age,我们重写了toString()方法,在这个方法中我们使用了Objects.toStringHelper方法,首先指定toString的类,然后依次add属性名称和属性值,可以使用omitNullValues()方法来指定忽略空值,最后调用其toString()方法
上面代码输出的结果是:
Student{id=1, name=Jim, age=13}
5.不可变集合
不可变对象有很多优点,包括:
- 当对象被不可信的库调用时,不可变形式是安全的;
- 不可变对象被多个线程调用时,不存在竞态条件问题
- 不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节);
- 不可变对象因为有固定不变,可以作为常量来安全使用。
创建对象的不可变拷贝是一项很好的防御性编程技巧。Guava为所有JDK标准集合类型和Guava新集合类型都提供了简单易用的不可变版本。
JDK也提供了Collections.unmodifiableXXX方法把集合包装为不可变形式,但我们认为不够好:
- 笨重而且累赘:不能舒适地用在所有想做防御性拷贝的场景;
- 不安全:要保证没人通过原集合的引用进行修改,返回的集合才是事实上不可变的;
- 低效:包装过的集合仍然保有可变集合的开销,比如并发修改的检查、散列表的额外空间,等等。
如果你没有修改某个集合的需求,或者希望某个集合保持不变时,把它防御性地拷贝到不可变集合是个很好的实践。
重要提示:所有Guava不可变集合的实现都不接受null值。我们对Google内部的代码库做过详细研究,发现只有5%的情况需要在集合中允许null元素,剩下的95%场景都是遇到null值就快速失败。如果你需要在不可变集合中使用null,请使用JDK中的Collections.unmodifiableXXX方法。更多细节建议请参考“使用和避免null”。
第二种方法使用of静态方法创建:
ImmutableSet.of("red","green","black","white","grey");
第三种方法使用copyOf静态方法创建:
ImmutableSet.copyOf(new String[]{"red","green","black","white","grey"});
6.Multimaps:一键多值的Map
有时候我们需要这样的数据类型Map<String,Collection<String>>,guava中的Multimap就是为了解决这类问题的。
Multimap提供了丰富的实现,所以你可以用它来替代程序里的Map<K, Collection<V>>,具体的实现如下:
实现 | Key实现 | Value实现 |
ArrayListMultimap | HashMap | ArrayList |
HashMultimap | HashMap | HashSet |
LinkedListMultimap | LinkedHashMap | LinkedList |
LinkedHashMultimap | LinkedHashMap | LinkedHashSet |
TreeMultimap | TreeMap | TreeSet |
ImmutableListMultimap | ImmutableMap | ImmutableList |
ImmutableSetMultimap | ImmutableMap | ImmutableSet |