简介
Java8对Comparator进行了优化,提供了很多非常实用的功能,让我们可以利用Comparator提供的函数就能完成基本的排序功能,而不用机械的自己实现compare函数。
集合sort
从Java8开始很多集合接口都添加了sort方法,这样就不需要使用Collections的sort函数了。
下面看一个List字符串排序的例子:
@Test
public void stringSort(){
LinkedList<String> names = new LinkedList<>();
names.add("allen");
names.add("dunn");
names.add("Bob");
names.add("cherry");
names.sort(String::compareToIgnoreCase);
System.out.println(names);
}
Comparator的naturalOrder与reversed
从Java8开始我们可以直接通过Comparator的naturalOrder获取一个比较通用的Comparator,只要要比较的元素实现了Comparable就可以。
并且还有一个reversed方法可以简单的获取倒序的Comparator。
还是看一个简单的例子:
@Test
public void naturalOrder(){
TreeSet<Long> nums = new TreeSet(Comparator.naturalOrder().reversed());
nums.add(1L);
nums.add(13L);
nums.add(8L);
nums.add(9L);
System.out.println(nums.pollFirst());
System.out.println(nums);
}
TreeSet我希望集合倒序怎么办?使用Comparator创建一个自然序的倒序Comparator就可以了。
Comparator的comparing
Comparator的comparing主要针对对象比较的,比如我有一个User对象,我需要根据User对象的名字排序怎么办?
@Test
public void comparingKey(){
List<User> userList = getUserList();
userList.sort(Comparator.comparing(User::getName));
System.out.println(userList);
}
详细的代码看后面完整示例
是不是非常简单,Java8之前,我们需要自己实现Comparator,现在只需要使用comparing方法告诉它怎样获取比较的字段就可以获取一个自然序的Comparator。
如果不想按自然序,想自定义怎么办?
comparing安排:
@Test
public void comparingKeyCom(){
List<User> userList = getUserList();
userList.sort(Comparator.comparing(User::getName,(fname,sname)->{
return fname.charAt(0) - fname.charAt(1);
}));
System.out.println(userList);
}
comparing的第一个参数,告诉它怎样获取比较的key,后一个参数告诉key怎样比较。
Comparator的thenComparing
如果我想根据2个字段排序怎么办?比如想根据id倒序,名字自然序。
thenComparing安排:
@Test
public void comparingComponent(){
List<User> userList = getUserList();
userList.sort(Comparator.comparing(User::getId).reversed().thenComparing(User::getName));
System.out.println(userList);
}
comparing选择id排序,reversed倒序,thenComparing然后根据名字自然序。
完整示例
import org.junit.Test;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeSet;
public class ComparatorTest {
@Test
public void stringSort(){
LinkedList<String> names = new LinkedList<>();
names.add("allen");
names.add("dunn");
names.add("Bob");
names.add("cherry");
names.sort(String::compareToIgnoreCase);
System.out.println(names);
}
@Test
public void naturalOrder(){
TreeSet<Long> nums = new TreeSet(Comparator.naturalOrder().reversed());
nums.add(1L);
nums.add(13L);
nums.add(8L);
nums.add(9L);
System.out.println(nums.pollFirst());
System.out.println(nums);
}
@Test
public void comparingKey(){
List<User> userList = getUserList();
userList.sort(Comparator.comparing(User::getName));
System.out.println(userList);
}
@Test
public void comparingKeyCom(){
List<User> userList = getUserList();
userList.sort(Comparator.comparing(User::getName,(fname,sname)->{
return fname.charAt(0) - fname.charAt(1);
}));
System.out.println(userList);
}
@Test
public void comparingComponent(){
List<User> userList = getUserList();
userList.sort(Comparator.comparing(User::getId).reversed().thenComparing(User::getName));
System.out.println(userList);
}
private static List<User> getUserList(){
LinkedList<User> users = new LinkedList<>();
users.add(new User(8,"allen"));
users.add(new User(5,"dunn"));
users.add(new User(5,"cherry"));
users.add(new User(3,"bob"));
return users;
}
private static final class User{
private Integer id;
private String name;
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
}