guava之比较器(1)

本文介绍了Google的Guava库中的Ordering类,作为Comparator的扩展,它提供了链式调用来定制和增强比较器的功能。通过一个小实例展示了如何创建排序器,包括使用natural()方法进行自然排序,以及如何在不改变原始类的情况下,通过Function接口和NullsFirst()等方法实现按姓名排序并处理null值的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于一个学习java加工作两年还不到的程序员,这个时候接触一种java类库的扩展似乎不太合适,但是学习东西的新鲜感还是嗖嗖嗖的飞了出来,在网上浏览文章时,无意间看到了google的guava项目,觉得有点意思,就搜索有关guava的学习教程,粗略学习尝试之后,便感觉对这个类库已经放不下了,后面会继续努力学的更深入点。

现在在这里,主要简单介绍一个guava里面强大的“流畅风格比较器”!

排序器——Ordering

ordering实现了java的conparator接口,Ordering把很多基于Comparator的静态方法(如Collections.max)包装为自己的实例方法(非静态方法),并且提供了链式调用方法,来定制和增强现有的比较器。

怎么建立排序器呢?或者说我们可以建个怎样的排序器呢?

一、小实例

1.首先,我们先建立一个实体类User

public class User {
private String username;
private int age;
private String password;
public User() {
}
public User(String username, int age) {
super();
this.username = username;
this.age = age;
}

public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

2.编写测试用例

@Test
public void test01(){
User user1 = new User();
user1.setUsername("zhagnsan");
user1.setAge(22);
user1.setPassword("123");
User user2 = new User();
user2.setUsername("aisi");
user2.setAge(2);
user2.setPassword("123");
User user3 = new User();
user3.setUsername("wangwu");
user3.setAge(56);
user3.setPassword("123");
List<User> us = new ArrayList<User>();
us.add(user1);
us.add(user2);
us.add(user3);
//创建ordering实例,并编写排序规则
Ordering<User> ordering = new Ordering<User>() {
@Override
public int compare(User u1, User u2) {
return Ints.compare(u1.getAge(), u2.getAge());
}
};
Collections.sort(us, ordering);
for (User user : us) {
System.out.println(user.getUsername()+"..."+user.getAge()+"..."+user.getPassword());
}
}
排序结果


通过这个,我们实现了按照年龄排序,实现java原生排序的写法,接下来我们来看一看其他不一样的写法和用法

二、主要方法和用法

1、natural()   对可排序类型做自然排序,如按照数字大小,日期按照先后排序

(1)通过描述我们知道,如果单独调用这个方法,我们首先要保证排序的类是可排序的,这里用到的实现可排序的,就是java提供的comparable接口,需要我们的User类实现此接口,并实现compareTo方法



中间的代码省略
用法:

//调用自然排序规则
Ordering<User> ordering = Ordering.natural();
Collections.sort(us, ordering);
//其他代码和小实例测试代码一样

结果:

我们可以看到,实现了按照姓名的自然排序,如果觉得这样写还是不过瘾

那么我们这些写,不对User类实现可排序,而在我们调用排序方法的时候,实现排序规则

(2)实现按照姓名排序,且名字为null的排在前面(此时User没有实现comparable接口)

用法:

//调用自然排序,自定义排序列,并且为null的排在前面
Ordering<User> ordering = Ordering.natural().nullsFirst().onResultOf(new Function<User, String>() {
@Override
public String apply(User u) {
return u.getUsername();
}
});
Collections.sort(us, ordering);
//其余代码省略,同小案例
结果:

我们可以看到实现了按照名字的自然排序,并且实现了将名字为null的排在前面

这里简单讲解一下上面的方法:

Function接口:第一个参数是要排序的参数的所在类,第二个参数是要排序的参数的类型,实现apply方法,返回我们要自然排序的参数

NullsFirst():此方法实现了排序参数为null的排在前面的效果

此外还有 NullsLast(),实现null参数排在后面的效果;reverse()方法,实现将排序好的结果反向输出

注意:

由于guava使用了大量的链式编程,因此我们可以一路在方法后面点出其他的方法,如上面的reverse()方法,我们可以在natural()方法后面调用,也可以在NullsFirst()方法后面调用,还可以在OnResultOf()后面调用。
但是这里特别要注意的,这里的实现使用了装饰模式,因此每调用一个方法,都是对上一个方法调用结果的封装,因此调用的顺序要注意,否则会得到意想不到的结果甚至报错
例如上面的例子,如果在OnResultOf()方法后面调用NullsFirst()方法,那么就会报空指针异常
然而,如果是正常且合理的调用,则能够组合出很多效果,这也是这个比较器的强大,
例如:
Ordering<User> ordering = Ordering.natural().reverse().nullsFirst().onResultOf(new Function<User, String>() {
@Override
public String apply(User u) {
return u.getUsername();
}
});
Collections.sort(us, ordering);
//此代码就实现了按照名字自然排序,然后将其反序输出,然后将null值得排在前列
更多的组合使用方法,我们可以自己再去探索
我也就简单介绍到这,后面的我慢慢介绍,友友们可以自己去搜搜相关文档,嘿嘿。。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值