您的位置:首页 > 其它

一、Guava基本工具

2017-04-10 23:35 253 查看

使用和避免null(Optional)

null会引起歧义,会造成让人迷惑的错误,有时也会让人感到不爽。Guava中的许多工具遇到null时,会拒绝或者马上报错,而不是盲目的接受。

鉴于此google的guava库中提供了Optional接口来使null快速失败,即在可能为null的对象上做了一层封装,在使用Optional静态方法of时,如果传入的参数为null就抛出NullPointerException异常。

在Guava中Optional类就是用来强制提醒程序员,注意对Null的判断。

Optional的另外几个方法

1. Optional.of(T) 为Optional赋值,当T为Null直接抛NullPointException,建议这个方法在调用的时候直接传常量,不要传变量

2. Optional.fromNullable(T) 为Optional赋值,当T为Null则使用默认值。建议与or方法一起用,风骚无比

3. Optional.absent() 为Optional赋值,采用默认值

4. T or(T) 当Optional的值为null时,使用or赋予的值返回。与fromNullable是一对好基友

5. T get() 当Optional的值为null时,抛出IllegalStateException,返回Optional的值

6. boolean isPresent() 如果Optional存在值,则返回True

7. T orNull() 当Optional的值为null时,则返回Null。否则返回Optional的值

8. Set asSet() 将Optional中的值转为一个Set返回,当然只有一个值啦,或者为空,当值为null时。

使用Optional的意义?

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

public static void testOptional() {
Optional of = Optional.of(6);//获得一个Optional对象,其内部包含了一个非null的T数据类型实例,若T=null,则立刻报错
//   Optional.of(null);
Optional<Object> absent = Optional.absent();//空对象的optional
LocalDateTime time = null;
Optional.fromNullable(time);//将一个T的实例转换为Optional对象,T的实例可以不为空,也可以为空[Optional.fromNullable(null),和Optional.absent()等价。
if (absent.isPresent()) {
//isPresent方法用来检查Optional实例中是否包含值
of.get();//取值
System.out.println("=================================");
}
System.err.println(absent.or(7));//:若Optional实例中包含了不为空和null的实例,返回Optional包含的该T实例,否则返回输入的T实例作为默认值
System.err.println(of.or("0ss"));
}


Preconditions优雅的检验参数

使方法的条件检查更简单。

Guava在Preconditions类中提供了若干前置条件判断的实用方法,我们强烈建议在Eclipse中静态导入这些方法。每个方法都有三个变种:

a) 没有额外参数:抛出的异常中没有错误消息;

b) 有一个Object对象作为额外参数:抛出的异常使用Object.toString() 作为错误消息;

c) 有一个String对象作为额外参数,并且有一组任意数量的附加Object对象:这个变种处理异常消息的方式有点类似printf,但考虑GWT的兼容性和效率,只支持%s指示符。

方法声明(不包括额外参数)描述检查失败时抛出的异常
checkArgument(boolean)检查boolean是否为true,用来检查传递给方法的参数。IllegalArgumentException
checkNotNull(T)检查value是否为null,该方法直接返回value,因此可以内嵌使用checkNotNull。NullPointerException
checkState(boolean)用来检查对象的某些状态。IllegalStateException
checkElementIndex(int index, int size)检查index作为索引值对某个列表、字符串或数组是否有效。IndexOutOf
checkPositionIndex(int index, int size)检查index作为位置值对某个列表、字符串或数组是否有效IndexOutOfBoundsException
checkPositionIndexes(int start, int end, int size)检查[start, end]表示的位置范围对某个列表、字符串或数组是否有效*IndexOutOfBoundsException
public static void getPersonByPrecondition(int age,String neme)throws Exception{
checkNotNull(neme, "neme为null");
/*checkArgument(boolean) :
  功能描述:检查boolean是否为真。 用作方法中检查参数
  失败时抛出的异常类型: IllegalArgumentException*/
checkArgument(neme.length()>0, "neme为\'\'");
checkArgument(age>0, "age 必须大于0");
System.out.println("a person age:"+age+",neme:"+neme);

}

public static void checkState(List<Integer> intList, int index)throws Exception{
//表达式为true不抛异常
Preconditions.checkState(intList.size()<index, " intList size 不能大于"+index);
}

public static void checkPositionIndex(List<Integer> intList,int index) throws Exception{
Preconditions.checkPositionIndex(index, intList.size(), "index "+index+" 不在 list中, List size为:"+intList.size());
}

public static void checkPositionIndexes(List<Integer> intList,int start,int end) throws Exception{
Preconditions.checkPositionIndexes(start, end, intList.size());
}

public static void checkElementIndex(List<Integer> intList,int index) throws Exception{
Preconditions.checkElementIndex(index, intList.size(),"index 为 "+index+" 不在 list中, List size为: "+intList.size());
}


常见的对象方法(Objects)

简化Object方法实现,如hashCode()和toString();

a) equals

当一个对象中的字段可以为null时,实现Object.equals方法会很痛苦,因为不得不分别对它们进行null检查。使用Objects.equal帮助你执行null敏感的equals判断,从而避免抛出NullPointerException。

b) hashCode

用对象的所有字段作散列[hash]运算应当更简单。Guava的Objects.hashCode(Object…)会对传入的字段序列计算出合理的、顺序敏感的散列值。你可以使用Objects.hashCode(field1, field2, …, fieldn)来代替手动计算散列值。

c) toString

好的toString方法在调试时是无价之宝,但是编写toString方法有时候却很痛苦。使用 Objects.toStringHelper可以轻松编写有用的toString方法。

package object;

import com.google.common.base.Objects;
import org.junit.Test;

/**
* Created by LF on 2017/2/21.
*/
public class ObjectTest {
@Test
public void equalTest() {
System.out.println(Objects.equal("a", "a"));
System.out.println(Objects.equal(null, "a"));
System.out.println(Objects.equal("a", null));
System.out.println(Objects.equal(null, null));
}

@Test
public void equalPersonTest() {
System.out.println(Objects.equal(new Person("peida",23), new Person("peida",23)));
Person person=new Person("peida",23);
System.out.println(Objects.equal(person,person));
}
@Test
public void hashcodeTest() {
System.out.println(Objects.hashCode("a"));
System.out.println(Objects.hashCode("a"));
System.out.println(Objects.hashCode("a","b"));
System.out.println(Objects.hashCode("b","a"));
System.out.println(Objects.hashCode("a","b","c"));

Person person=new Person("peida",23);
System.out.println(Objects.hashCode(person));
System.out.println(Objects.hashCode(person));
}
@Test
public void toStringTest() {
//System.out.println(Objects.toStringHelper(this).add("x", 1).toString());
//System.out.println(Objects.toStringHelper(Person.class).add("x", 1).toString());
//
//Person person=new Person("peida",23);
//String result = Objects.toStringHelper(Person.class)
//        .add("name", person.name)
//        .add("age", person.age).toString();
//System.out.print(result);
}
}

class Person {
public String name;
public int age;

Person(String name, int age) {
this.name = name;
this.age = age;
}
}


排序

排序器[Ordering]是Guava流畅风格比较器[Comparator]的实现,它可以用来为构建复杂的比较器,以完成集合排序的功能。

从实现上说,Ordering实例就是一个特殊的Comparator实例。Ordering把很多基于Comparator的静态方法(如Collections.max)包装为自己的实例方法(非静态方法),并且提供了链式调用方法,来定制和增强现有的比较器。

创建排序器:常见的排序器可以由下面的静态方法创建

natural():使用Comparable类型的自然顺序, 例如:整数从小到大,字符串是按字典顺序;

usingToString() :使用toString()返回的字符串按字典顺序进行排序;

arbitrary() :返回一个所有对象的任意顺序, 即compare(a, b) == 0 就是 a == b (identity equality)。 本身的排序是没有任何含义, 但是在VM的生命周期是一个常量。

@Test
public void testStaticOrdering(){
List<String> list = Lists.newArrayList();
list.add("peida");
list.add("jerry");
list.add("harry");
list.add("eva");
list.add("jhon");
list.add("neron");

System.out.println("原来的顺序:"+ list);

Ordering<String> naturalOrdering = Ordering.natural();
System.out.println("使用Comparable类型的自然顺序:"+ naturalOrdering.sortedCopy(list));

Ordering<Object> usingToStringOrdering = Ordering.usingToString();
System.out.println("使用toString()返回的字符串按字典顺序进行排序:"+ usingToStringOrdering.sortedCopy(list));

Ordering<Object> arbitraryOrdering = Ordering.arbitrary();
System.out.println("所有对象的任意顺序:"+ arbitraryOrdering.sortedCopy(list));
}


操作方法:

reverse(): 返回与当前Ordering相反的排序:

nullsFirst(): 返回一个将null放在non-null元素之前的Ordering,其他的和原始的Ordering一样;

nullsLast():返回一个将null放在non-null元素之后的Ordering,其他的和原始的Ordering一样;

compound(Comparator):返回一个使用Comparator的Ordering,Comparator作为第二排序元素,例如对bug列表进行排序,先根据bug的级别,再根据优先级进行排序;

lexicographical():返回一个按照字典元素迭代的Ordering;

onResultOf(Function):将function应用在各个元素上之后, 在使用原始ordering进行排序;

greatestOf(Iterable iterable, int k):返回指定的第k个可迭代的最大的元素,按照这个从最大到最小的顺序。是不稳定的。

leastOf(Iterable iterable,int k):返回指定的第k个可迭代的最小的元素,按照这个从最小到最大的顺序。是不稳定的。

isOrdered(Iterable):是否有序,Iterable不能少于2个元素。

isStrictlyOrdered(Iterable):是否严格有序。请注意,Iterable不能少于两个元素。

@Test
public void testOrdering() {
List<String> list = Lists.newArrayList();
list.add("peida");
list.add("jerry");
list.add("harry");
list.add("eva");
list.add("jhon");
list.add("neron");

List<Integer> listReduce = Lists.newArrayList();
for (int i = 9; i > 0; i--) {
listReduce.add(i);
}

List<Integer> listtest = Lists.newArrayList();
listtest.add(1);
listtest.add(1);
listtest.add(1);
listtest.add(2);

System.out.println("listtest:" + listtest);
Ordering<Integer> naturalIntReduceOrdering = Ordering.natural();
System.out.println("是否有序" + naturalIntReduceOrdering.isOrdered(listtest));

System.out.println("是否严格有序" + naturalIntReduceOrdering.isStrictlyOrdered(listtest));

List<String> cba = ImmutableList.of("c", "b", "a");
Ordering<String> natural = Ordering.natural();
System.out.println("max:" + natural.max(cba));
System.out.println("min:" + natural.min(cba));

System.out.println("返回指定的第k个可迭代的最小的元素,按照这个从最小到最大的顺序。是不稳定的。:" + natural.leastOf(cba, 2));

Ordering<String> naturalOrdering = Ordering.natural();
System.out.println("回指定的第k个可迭代的最大的元素,按照这个从最大到最小的顺序:" + naturalOrdering.greatestOf(list, 3));
list.add(null);
System.out.println(" add null list:" + list);
System.out.println("返回一个将null放在non-null元素之前的Ordering,其他的和原始的Ordering一样 :" + naturalOrdering.nullsFirst().sortedCopy(list));
System.out.println("返回一个将null放在non-null元素之后的Ordering :" + naturalOrdering.nullsLast().sortedCopy(list));
}


Throwable类

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  guava