必威体育Betway必威体育官网
当前位置:首页 > IT技术

Guava(一)

时间:2019-07-27 05:41:06来源:IT技术作者:seo实验室小编阅读:82次「手机版」
 

guava

目录

【基本工具

一、optional

    针对java开发中null的问题,guava设计了Optional类。虽然util包下也有自带的Optional类,但是Guava对其做了更好的处理。Optional 用来表示可能为null的T类型的引用,两个实现类Present(存在)和Absent(不存在)。

那么Optional究竟有什么用呢,我们来看一下主要的方法:

  1. Optional.fromNullable(T) 创建指定引用的Optional实例,若引用为null则表示缺失
  2. boolean isPresent() 如果Optional包含非null的引用(引用存在),返回true
String s1 = null;
String s2 = "1";
Optional opt1 = Optional.fromNullable(s1);
Optional opt2 = Optional.fromNullable(s2);
System.out.println(opt1.isPresent());  // false
System.out.println(opt2.isPresent());  // true
  1. T get() 返回Optional所包含的引用,若引用缺失,则抛出java.lang.IllegalStateException
  2. T or(T) 返回Optional所包含的引用,若引用缺失,返回指定的值
  3. T orNull() 返回Optional所包含的引用,若引用缺失,返回null
// 紧接着上面的例子
System.out.println(opt1.or("0"));   // 0
System.out.println(opt1.orNull());  // null
System.out.println(opt2.get());     // 1
System.out.println(opt2.or("0"));   // 1
System.out.println(opt2.orNull());  // 1
  1. Optional.of(T) 创建指定引用的Optional实例,若引用为null则快速失败
Optional.of("0");
Optional.of(null);  // NullPointerException

Optional存在的意义是什么?看下官方的解释:

    使用Optional除了赋予null语义,增加了可读性,最大的优点在于它是一种傻瓜式的防护。Optional迫使你积极思考引用缺失的情况,因为你必须显式地从Optional获取引用。直接使用null很容易让人忘掉某些情形,尽管FindBugs可以帮助查找null相关的问题,但是我们还是认为它并不能准确地定位问题根源。

    如同输入参数,方法的返回值也可能是null。和其他人一样,你绝对很可能会忘记别人写的方法method(a,b)会返回一个null,就好像当你实现method(a,b)时,也很可能忘记输入参数a可以为null。将方法的返回类型指定为Optional,也可以迫使调用者思考返回的引用缺失的情形。

    总的来说Optional实际上就是一个提醒,让开发者时刻注意null。

二、前置条件

Guava封装好了几种前置条件的实用方法,能够让判断条件更简单。

每种方法都有3个重载函数

● 没有额外参数,只抛出异常,无错误信息

● 有一个Object类型的额外参数,通过toString方法输出错误信息

● 有一个String对象和Object数组作为额外参数,String中通过’%s’占位符依次输出数组中的参数值

方法声明 描述 失败抛出异常
checkArgument(boolean) 检查boolean是否为true,用于参数检查 illegalargumentException
checkState(boolean) 检查对象的某些状态 IllegalStateException
checknotnull(T) 检查T的实例是否为null,直接返回该实例 NullPointerException
checkElementIndex(int index, int size) 检查索引是否有效(index>=0&&index<size) IndexOutOfBoundsException
checkPositionIndex(int index, int size) 检查位置是否有效(index>=0&&index<=size) IndexOutOfBoundsException
checkPositionIndexes(int start, int end, int size) 检查位置在[start, end]是否有效 IndexOutOfBoundsException

有这些前置条件可以省去很多重复的判断代码

// 直接 static 引入即可
import static com.Google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;

checkNotNull(reference, ...);
checkArgument(expression, ...);
checkState(expression, ...);

三、Objects方法

Guava提供的Objects与JDK util包下的Objects有些许相似的地方。

  1. equal(Object a, Object b) 忽略null的情况,可直接比较,与JDK Objects.equals方法相同。
  2. hashCode(Object… objects) hash运算,与JDK Objects.hash方法相同。
  3. toString,Guava的Objects提供了toStringHelper来实现toString方法,目前已过时,个人建议直接使用lombok注解生成。
Objects.toStringHelper("className").add("attr", value).toString();
  1. 这里值得推荐的是比较器ComparisonChain:

    之前实现比较方法是需要自定义实现compare或compareTo方法

public class Student implements Comparable<Student> {
	private Double score;
	private String name;
	private Long number;

	@Override
	public int compareTo(Student student) {
		int compare = score.compareTo(student.score);
		if (compare != 0) {
			return compare;
		}

		// 分数相同,比较姓名
		compare = name.compareTo(student.name);
		if (compare != 0) {
			return compare;
		}

		// 比较学号
		return number.compareTo(student.number);
	}
}

以上首先是根据学生成绩排序,成绩相同再根据姓名排序,若在相同则根据学号排序,使用ComparisonChain比较的代码如下:

@Override
public int compareTo(Student student) {
return ComparisonChain.start()
.compare(score, student.score)
.compare(name, student.name)
.compare(number, student.number, ordering.natural().nullsLast())
.result();
}

    两者相较很明显后者直观明了,ComparisonChain会根据compare的顺序依次比较,直至发现非0的结果,之后的比较会直接忽略。另外compare中的第三个参数还可以定义排序顺序,类Ordering也是由Guava提供,本文第四节会做出介绍。

四、Guava强大的比较器

    首先"强大"两字来源于官网的标题,不过个人认为确实强大~~

通过源码可以看出Ordering实际上是Comparator的实例,并且拓展出了链式调用方法,使用起来非常方便。

  1. 创建排序

    ● natural() 对排序类型做自然排序

    ● usingToString() 按对象toString()方法做字典排序

    ● from(Comparator) 转化排序器

    除此外还可以直接继承Ordering:

Ordering<String> ordering = new Ordering<String>() {
  		@Override
  		public int compare(String left, String right) {
  			return left.compareTo(right);
  		}
  	};
  1. 链式调用方法

    所谓链式调用就是由给定的排序器衍生出其他排序器

    方法|描述

    ----|----

    reverse()|倒叙排序

    nullsFirst()|排序中,把null值拍到最前

    nullsLast()|排序中,把null值拍到最后

    compound(Comparator)|合成比较器,处理当前排序器中的相等情况

    lexicographical()|返回按字典迭代的排序器

    onResultOf(Function)|对集合调用Function,再按返回值排序

    注:Function为Guava的函数式编程,在第五章中会介绍。

    第三节中的 Ordering.natural().nullsLast() 就是链式调用,但要注意链式调用应从后往前读,即先调用nullsLast将null元素置后,再调用natural()进行自然排序。

注:用compound方法包装排序器时,就不应遵循从后往前读的原则。为了避免理解上的混乱,请不要把compound写在一长串链式调用的中间,你可以另起一行,在链中最先或最后调用compound。

3. 其他方法

方法 描述 另请参见
greatestOf(Iterable iterable, int k) 获取可迭代对象中最大的k个元素。 leastOf
isOrdered(Iterable) 判断可迭代对象是否已按排序器排序:允许有排序值相等的元素。 isStrictlyOrdered
sortedCopy(Iterable) 判断可迭代对象是否已严格按排序器排序:不允许排序值相等的元素。 immutableSortedCopy
min(E, E) 返回两个参数中最小的那个。如果相等,则返回第一个参数。 max(E, E)
min(E, E, E, E…) 返回多个参数中最小的那个。如果有超过一个参数都最小,则返回第一个最小的参数。 max(E, E, E, E…)
min(Iterable) 返回迭代器中最小的元素。如果可迭代对象中没有元素,则抛出NoSuchElementException。 max(Iterable),min(Iterator),max(Iterator)

五、 throwables

    Guava还提供了简化异常和错误的传播与检查方法,由于实际开发中用到的不多,这里不再介绍,详细可以查看中文文档Google Guava: Throwables

相关阅读

[Google Guava]--Optional类

扯淡一下:刚刚换了新工作,新的公司,新的同事,很好的伙伴们,都很喜欢;新的业务,新的技术,新的挑战:开启新的旅程,Fighting!  这阵子一直了解

分享到:

栏目导航

推荐阅读

热门阅读