Java8 Comparator技巧

简介

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 + '\'' +
                    '}';
        }
    }
}
上一篇:系统学习Lambda表达式


下一篇:java-具有字段的比较器类