集合排序

对集合进行处理,入参是一个集合,出参是按照一定规则排好序的集合。

import java.security.SecureRandom;
import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;

public class SortTest {
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(new Person("John", 20), //
                new Person("Sara", 20), //
                new Person("Jane", 18), //
                new Person("Greg", 35));//
        //按年龄升序排列
        Collections.sort(people, new Comparator<Person>() {
            @Override
            public int compare(Person p1, Person p2) {
                return p1.getAge() - p2.getAge();
            }
        });
        System.out.println(people);

        //按年龄降序排列
        people.sort(Comparator.comparingInt(Person::getAge).reversed());
        System.out.println(people);

        //按年龄升序排列
        people = people.stream()
                .sorted(Comparator.comparing(Person::getAge))
                .collect(Collectors.toList());
        System.out.println(people);

        //按年龄降序排列
        people = people.stream()
                .sorted((p1, p2) -> Integer.valueOf(p2.getAge()).compareTo(Integer.valueOf(p1.getAge())))
                .collect(Collectors.toList());
        System.out.println(people);


        //按年龄升序、姓名降序排列
        people = people.stream().sorted((p1, p2) -> {
            int ageCom = Integer.valueOf(p1.getAge()).compareTo(Integer.valueOf(p2.getAge()));
            int nameCom = p2.getName().compareToIgnoreCase(p1.getName());
            if (ageCom == 0) {
                return nameCom;
            }
            return ageCom;
        }).collect(Collectors.toList());
        System.out.println(people);


        Map<String, Object> mapA = new HashMap<>();
        mapA.put("name", "John");
        mapA.put("age", 20);


        Map<String, Object> mapB = new HashMap<>();
        mapB.put("name", "Jane");
        mapB.put("age", 18);


        Map<String, Object> mapC = new HashMap<>();
        mapC.put("name", "Greg");
        mapC.put("age", 35);

        Map<String, Object> mapD = new HashMap<>();
        mapD.put("name", "Sara");
        mapD.put("age", 21);


        List<Map<String, Object>> list = new ArrayList<>();
        list.add(mapA);
        list.add(mapB);
        list.add(mapC);
        list.add(mapD);

        //按姓名升序排列
        list.sort(new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> map1, Map<String, Object> map2) {
                return ((String) map1.get("name")).compareToIgnoreCase((String) map2.get("name"));
            }
        });
        System.out.println(list);

        //按姓名降序排列
        Collections.sort(list, new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> map1, Map<String, Object> map2) {
                return ((String) map1.get("name")).compareToIgnoreCase((String) map2.get("name"));
            }
        }.reversed());
        System.out.println(list);

        //按姓名升序排列
        list = list.stream().sorted(new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> map1, Map<String, Object> map2) {
                return ((String) map1.get("name")).compareToIgnoreCase((String) map2.get("name"));
            }
        }).collect(Collectors.toList());
        System.out.println(list);

        //按姓名降序排列
        list = list.stream().sorted((p1, p2) -> ((String) p2.get("name")).compareToIgnoreCase((String) p1.get("name"))).collect(Collectors.toList());
        System.out.println(list);


        //多条件排序
        list.remove(mapD);
        Map<String, Object> mapE = new HashMap<>();
        mapE.put("name", "Greg");
        mapE.put("age", 19);
        list.add(mapE);
        Collections.shuffle(list, new SecureRandom());

        list.sort(new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                //姓名升系
                int nameC = String.valueOf(o1.get("name")).compareToIgnoreCase(String.valueOf(o2.get("name")));
                //年龄降序
                int ageC = ((Integer) o2.get("age")).compareTo((Integer) o1.get("age"));
                if (nameC == 0) {
                    return ageC;
                }
                return nameC;
            }
        });
        System.out.println(list);
    }
}

class Person {
    private String name;
    private int age;

    public Person(String theName, int theAge) {
        name = theName;
        age = theAge;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String toString() {
        return JSON.toJSONString(this);
    }
}

在java8之前,对集合排序只能用Collections集合工具类的sort静态方法  public static <T> void sort(List<T> list, Comparator<? super T> c) {}

传入要排序的list和Comparator实例即可。Comparator接口有2个方法,int compare(T o1, T o2)和boolean equals(Object obj),由于所有类都继承了Object类,而Object已经实现了equals方法,所以Comparator接口相当于只有一个int compare(T o1, T o2)方法,那么就可以参考Runnable接口的思路,创建一个Comparator接口的匿名实现类,在匿名类中实现compare方法即可。

Comparator支持泛型,可以指定要排序元素的类型,这就有上例中的

//按年龄升序排列
Collections.sort(people, new Comparator<Person>() {
        @Override
        public int compare(Person p1, Person p2) {
            return p1.getAge() - p2.getAge();
        }
});

java1.8在List接口中新增了实例方法sort(Comparator<? super E> c),并提供了默认实现,只需要传入一个Comparator实例即可。此时的Comparator实例既可以用匿名内部类的方式,也可以用java8独有的方式。

1.java8在Comparator接口中新增了很多静态方法可以直接得到Comparator实例,有

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor)

public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor)

public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor)

public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor)

还可以通过Comparator的reversed()实例方法对其进行反转,由升序转为降序或者由降序转为升序

于是就有了上例中的

people.sort(Comparator.comparingInt(Person::getAge));

2.利用java8在Collection接口中新增的stream()默认方法,把Collection对象转换成Stream对象,然后利用Stream的Stream<T> sorted(Comparator<? super T> comparator)实例方法,也是需要传入一个Comparator实例。

people = people.stream().sorted(Comparator.comparingInt(Person::getAge)).collect(Collectors.toList());

利用lambda表达式,Comparator实例也可通过下面方式获得   (p1,p2)->Integer.valueOf(p1.getAge()).compareTo(Integer.valueOf(p2.getAge()))

people = people.stream().sorted((p1,p2)->Integer.valueOf(p1.getAge()).compareTo(Integer.valueOf(p2.getAge()))).collect(Collectors.toList());

如果是多个排序条件的话,如按年龄升序、姓名升序排列,如下

people = people.stream().sorted(Comparator.comparingInt(Person::getAge).thenComparing(Person::getName)).collect(Collectors.toList());

按年龄升序、姓名降序排列,如下

people = people.stream().sorted((p1, p2) -> {
        int ageCom = Integer.valueOf(p1.getAge()).compareTo(Integer.valueOf(p2.getAge()));
        int nameCom = p2.getName().compareToIgnoreCase(p1.getName());
        if (ageCom == 0) {
            return nameCom;
        }
        return ageCom;
}).collect(Collectors.toList());

List中元素不是自定义类而是Map时,排序方法也是差不多的,唯一的不同就是只能用lambda表达式创建Comparator实例,而用Comparator的静态方法创建的实例则不能用。

原文地址:https://www.cnblogs.com/koushr/p/5873435.html