一, 引子
Guava 的经典很大一部分原因来源于对于基础工具类的封装, 使用这些类能够让我们的代码更加优雅且完善, 这些类大部分都在 com.google.common.base 包下.
注: JDK 有很多借鉴 guava 的地方, 本文只讲解 guava, 如果 jdk 中有相同的想法, 不必疑虑.
二, 基本工具
按照官网介绍, Guava base 包下有一些经典工具, 如下:
2.1 Optional<T>
1. 作用
在构造对象的时候就明确申明该对象是否可能为 null, 快速失败拒绝 null 值, 可以避免空指针异常.
2. 简单使用
- /**
- * @Description Optional: 一个指向值对象引用的对象实例, 使得构造对象时就明确申明是否支持 null
- * @author denny
- * @date 2018/7/24 下午 2:23
- */
- public class OptionalTest {
- public static void main(String[] args) {
- Integer a = null;
- Integer b = 1;
- // 支持 null, 非 null
- Optional<Integer> optionalA1 = Optional.fromNullable(a);
- Optional<Integer> optionalA2 = Optional.fromNullable(b);
- // 不支持 null, 参数为 null 报错
- Optional<Integer> optionalB = Optional.of(b);
- // 不包含引用对象的实例()
- Optional<Integer> optionalC = Optional.absent();
- // 不存在实例, 不进入
- if(optionalA1.isPresent()){
- System.out.println("A1 get="+optionalA1.get());
- }
- // 存在实例, 进入
- if(optionalA2.isPresent()){
- System.out.println("A2 get="+optionalA2.get());
- }
- // 存在实例, 进入
- if(optionalB.isPresent()){
- System.out.println("B get="+optionalB.get());
- }
- // 不存在实例, 不进入
- if(optionalC.isPresent()){
- System.out.println("C get="+optionalC.get());
- }
- }
- }
结果如下:
- A2 get=1 B get=1
- 2.2 Preconditions
1. 作用
前置条件校验, 让方法中的条件检查更简单.
2. 简单使用
- /**
- * @Description 前置条件校验
- * @author denny
- * @date 2018/7/24 下午 3:14
- */
- public class PreconditionsTest {
- public static void main(String[] args) {
- /** 1. 空指针校验 */
- Integer a = null;
- // 直接抛出空指针异常
- Preconditions.checkNotNull(a);
- // 抛出指定错误消息的空指针异常
- Preconditions.checkNotNull(a,"a is null!");
- // 抛出指定错误消息 (指定参数替换掉 %s) 的空指针异常
- Preconditions.checkNotNull(a,"a is null ,a=%s",a);
- /** 2. 方法入参校验 */
- // 方法入参校验: 校验第一参是否 true
- Preconditions.checkArgument(a!=null && a>=0,"参数 a 不满足条件! a=%s",a);
- /** 3. 检查对象的状态 */
- // 模拟: 订单号作为方法入参, 修改订单状态为已完成.
- Order order = Order.builder().id(1).build();
- // 状态校验, 非入参校验
- Preconditions.checkState(order.getState()>0,"订单状态非法! status=%s",order.getState());
- /** 4. 下标越界校验 */
- List list = Lists.newArrayList(1,2,3);
- //Preconditions.checkElementIndex(5,list.size(),"下标非法!");
- /** 5. 下标越界, start<end 校验 */
- Preconditions.checkPositionIndexes(0,5,list.size());
- }
- }
- 2.3 Objects(JDK7 以上直接使用 java.util.Objects)
1. 作用
常见 Object 方法, 简化 Object 方法实现, 如 hashCode()和 toString().
2. 简单使用
4 个典型方法:
- equal,hashcode,toString,compare/compareTo
- /**
- * @Description 简化对象的一些方法
- * @author denny
- * @date 2018/7/24 下午 4:08
- */
- public class ObjectsTest {
- public static void main(String[] args) {
- /** 1.equals */
- //false
- System.out.println(Objects.equal("a",null));
- System.out.println(Objects.equal("a","b"));
- // true
- System.out.println(Objects.equal("a","a"));
- System.out.println(Objects.equal(null,null));
- /** 2.hashCode */
- Order order1 = Order.builder().id(1).state(2).build();
- Order order2 = Order.builder().id(2).state(1).build();
- System.out.println(Objects.hashCode(order1,order2));
- /** 2.toString */
- String str = MoreObjects.toStringHelper(order1).add("x",1).toString();
- System.out.println(str);
- /** 2.compare/compareTo */
- // 这里比较订单大小, 比较顺序: id, 状态, 即先比较 ID 再比较状态, 有一个不相等就立即返回结果
- int result = ComparisonChain.start()
- .compare(order1.getId(),order2.getId())
- .compare(order1.getState(),order2.getState())
- .result();
- System.out.println(result);
- }
- }
打印结果:
- false
- false
- true
- true
- 114363
- Order{x=1}
- -1
- 2.4 Ordering<T>(JDK8 建议直接使用 Stream,Comparator)
1. 作用
排序,"流式风格比较器". 支持多重排序, 并使用到集合中. 这个类不在 base 包下, 在 collect 包下. 可能考虑到集合中元素排序吧...
2. 简单使用
reverse() : 获取语义相反的排序器
nullsFirst():null 值排到最前面.
nullsLast():null 值排到最后面.
compound(Comparator): 合成另一个比较器, 以处理当前排序器中的相等情况.
lexicographical(): 基于处理类型 T 的排序器, 返回该类型的可迭代对象 Iterable<T > 的排序器.
onResultOf(Function): 对集合中元素调用 Function, 再按返回值用当前排序器排序.
- package guava.base;
- import com.google.common.base.Function;
- import com.google.common.collect.Lists;
- import com.google.common.collect.Ordering;
- import guava.base.domain.Order;
- import java.util.List;
- /**
- * @Description 排序
- * @author denny
- * @date 2018/7/24 下午 6:01
- */
- public class OrderingTest {
- public static void main(String[] args) {
- /** 自然排序: 数字升序, 时间升序 */
- // 简单数据排序
- Ordering<Integer> integerOrdering = Ordering.natural().nullsFirst();
- List<Integer> list = Lists.newArrayList(1,3,null,5,4,2);
- // 自然排序, 空前置
- System.out.println("1. 自然排序:"+integerOrdering.sortedCopy(list));
- System.out.println("2. 自然反转排序:"+integerOrdering.reverse().sortedCopy(list));
- // 根据 apply 返回值排序
- Ordering<Order> orderOrdering = Ordering.natural().onResultOf(new Function<Order, Integer>() {
- public Integer apply(Order order){
- /* 订单 ID 自然排序 */
- return order.getId();
- }
- });
- List<Order> orders = Lists.newArrayList(new Order(1,0),new Order(3,1),new Order(2,2));
- System.out.println("3. 根据订单 ID 自然排序:"+orderOrdering.sortedCopy(orders));
- System.out.println("4. 根据订单 ID 自然排序, 求最大值:"+orderOrdering.max(orders));
- System.out.println("5. 根据订单 ID 自然排序, 求最小值:"+orderOrdering.min(orders));
- System.out.println("6. 求 ID 最小的 k 个元素:"+orderOrdering.leastOf(orders,2));
- System.out.println("7. 求 ID 最大的 k 个元素:"+orderOrdering.greatestOf(orders,2));
- }
- }
结果如下:
自然排序:[null, 1, 2, 3, 4, 5]
自然反转排序:[5, 4, 3, 2, 1, null]
根据订单 ID 自然排序:[Order(id=1, state=0), Order(id=2, state=2), Order(id=3, state=1)]
根据订单 ID 自然排序, 求最大值: Order(id=3, state=1)
根据订单 ID 自然排序, 求最小值: Order(id=1, state=0)
求 ID 最小的 k 个元素:[Order(id=1, state=0), Order(id=2, state=2)]
求 ID 最大的 k 个元素:[Order(id=3, state=1), Order(id=2, state=2)]
2.5 Throwables(不推荐使用)
1. 作用
异常支持, 简化了异常和错误的传播与检查.
2. 简单使用
目前 JDK7 已经是比较老的版本了, JDK7 自带多重捕获, 7 以及以上都不推荐使用 Throwables, 这里就不写使用了.
三, 总结
guava 虽然很经典, 但是因为 JDK 一直在迭代完善, 当 JDK 中有的东西时, 建议就不要用 guava 了. 基础工具中, Optional 和 Preconditions 还是可以用用, 其它的也就那样了, 各位自己看着用吧, 当然作为基础工具, 想要看 guava 源码还是有必要了解下知道是干嘛的.
来源: https://www.cnblogs.com/dennyzhangdd/p/9356416.html