Guava学习--Ordering与Java8排序比较

Guava-Ordering使用简介

guava是谷歌开源的一套Java类库,非常实用优雅。

Ordering继承了Comparator接口,它提供了流式的API,用于构建复杂的比较器:


1.链式构建比较器:

package org.lin.learn;

import java.util.ArrayList;
import java.util.Collections;

import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;

public class GuavaOrdering {
	public static void main(String[] args) {
		
		//构造一个比较器,先根据字符串长度排序,再按照字典序排序,null值置前
		Ordering ordering = Ordering.natural()
				.onResultOf((String str) -> {
					//使用Optional处理null值
					return Optional.fromNullable(str).or("").length();
				})
				.compound(Ordering.natural().nullsFirst()); //compound用于合并两个Ordering
		ArrayList names = Lists.newArrayList("Ram", "Shyam", "Mohan", "Sohan",
				"Ramesh", "Suresh", "Naresh", "Mahesh", null, "", "Vikas", "Deepak");
		Collections.sort(names, ordering);
		System.out.println(names);
	}
}

输出结果:


源码分析:

每次的链式调用,都会用后者包装前者的方式返回一个新的Ordering对象,如nullsFirst方法:

Guava学习--Ordering与Java8排序比较_第1张图片
Guava学习--Ordering与Java8排序比较_第2张图片

可以看到NullsFirstOrdering先用自己的逻辑比较,再用之前的比较器比较,所以链式调用的代码应该从后往前看。

但compound是个例外:


compound把参数中的比较器作为第二优先级的比较器。

2.一些实用的工具方法:

基于上面的代码:

System.out.println("最大的4个元素,从大到小:" + ordering.greatestOf(names, 4));
System.out.println("最小的4个元素,从小到大:" + ordering.leastOf(names, 4));
System.out.println("最大值:" + ordering.max(names));
System.out.println("最小值:" + ordering.min(names));

输出:

Guava学习--Ordering与Java8排序比较_第3张图片

Java8

如果看Ordering源码,注释写道,在Java8中Ordering已经过时了,因为大部分方法在Comparator中已经实现了!其他的方法可以在guava的Comparators工具类中找到。

所以在Java8中,写法应该是:

package org.lin.learn;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Optional;
import com.google.common.collect.Comparators;
import com.google.common.collect.Lists;

public class Java8Sorting {
	public static void main(String[] args) {
		ArrayList names = Lists.newArrayList("Ram", "Shyam", "Mohan", "Sohan",
				"Ramesh", "Suresh", "Naresh", "Mahesh", null, "", "Vikas", "Deepak");
		Comparator comparator = 
			Comparator.comparing((str) -> {
				//这是Java8的Optional
				return Optional.ofNullable(str).orElse("").length();
			})
			.thenComparing(Comparator.nullsFirst(Comparator.naturalOrder()));
		names.sort(comparator);
		System.out.println(names);
		System.out.println("最大的四个元素:" + names.stream().collect(Comparators.greatest(4, comparator)));
		System.out.println("最小的四个元素:" + names.stream().collect(Comparators.least(4, comparator)));
		System.out.println("最大的元素:" + names.stream().max(comparator).get());
		//遗憾的是,min内部使用Optional.of,null元素会抛空指针异常
		System.out.println("最小的元素:" + names.stream().min(comparator).get());
	}
}


输出:

Guava学习--Ordering与Java8排序比较_第4张图片

结论:

guava的Ordering和Optional,在Java8之前拥有非常先进的理念,它借助链式调用的方式,模拟了函数式编程,但在Java8之后,Ordering和guava的Optional可以说已经过时,取而代之的是Java强大的stream API 和 Comparator接口。得益于interface默认方法的支持,大部分Ordering的方法Comparator和Stream API已经实现了。

函数式编程:

1.以函数作为参数,Java中是传递函数式接口的对象,表现为匿名内部类或者Lambda表达式,也可以是方法引用

2.函数的链式调用,前一个函数的结果作为下一个函数的输入,在Java中表现为方法的链式调用

参考:

Java排序增强,方法引用

目前guava的类库只接触了小部分,给我的感觉是jdk,还有其他的开源框架,在很多地方借鉴了guava的思想,继续接触期待有其他发现。

你可能感兴趣的:(Java基础,Java最佳实践)