Java 8 基础教程 - Stream 排序和统计

1,710 阅读4分钟
原文链接: www.codemore.top

Collection 需要排序的时候可以使用Comparator和Comparable实现。在Java 8中,同样可以使用Comparator对Stream进行排序,本节中将使用Employee作为示例

public class Employee {
    private Integer id;
    private String firstName;
    private String lastName;
    private Integer age;
     
    public Employee(Integer id, String firstName, String lastName, Integer age){
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
     
    //Other getter and setter methods
     
    @Override
    public String toString() {
        return "\n["+this.id+","+this.firstName+","+this.lastName+","+this.age+"]";
    }
}

获取Employee的一个列表

private static List<Employee> getEmployees(){
    List<Employee> employees  = new ArrayList<>();
    employees.add(new Employee(1,"Lokesh", "Gupta", 32));
    employees.add(new Employee(2,"Aman", "Sharma", 28));
    employees.add(new Employee(3,"Aakash", "Yaadav", 52));
    employees.add(new Employee(4,"James", "Hedge", 72));
    employees.add(new Employee(5,"David", "Kameron", 19));
    employees.add(new Employee(6,"Yash", "Chopra", 25));
    employees.add(new Employee(7,"Karan", "Johar", 59));
    employees.add(new Employee(8,"Balaji", "Subbu", 88));
    employees.add(new Employee(9,"Vishu", "Bissi", 33));
    employees.add(new Employee(10,"Lokesh", "Ramachandran", 60));
    return employees;
}
根据firstName排序
 List<Employee> employees  = getEmployees();
     
    //Sort all employees by first name
    employees.sort(Comparator.comparing(e -> e.getFirstName()));
     
    //OR you can use below
    employees.sort(Comparator.comparing(Employee::getFirstName));
     
    //Let's print the sorted list
    System.out.println(employees);

输出

[[3,Aakash,Yaadav,52],
[2,Aman,Sharma,28],
[8,Balaji,Subbu,88],
[5,David,Kameron,19],
[4,James,Hedge,72],
[7,Karan,Johar,59],
[1,Lokesh,Gupta,32],
[10,Lokesh,Ramachandran,60],
[9,Vishu,Bissi,33],
[6,Yash,Chopra,25]]
排序反转

使用Comparator.reversed()可以反转一个排序

List<Employee> employees  = getEmployees();
     
    //Sort all employees by first name; And then reversed
    Comparator<Employee> comparator = Comparator.comparing(e -> e.getFirstName());
    employees.sort(comparator.reversed());
     
    //Let's print the sorted list
    System.out.println(employees);

输出

[[6,Yash,Chopra,25],
[9,Vishu,Bissi,33],
[1,Lokesh,Gupta,32],
[10,Lokesh,Ramachandran,60],
[7,Karan,Johar,59],
[4,James,Hedge,72],
[5,David,Kameron,19],
[8,Balaji,Subbu,88],
[2,Aman,Sharma,28],
[3,Aakash,Yaadav,52]]
通过lastName排序
   List<Employee> employees  = getEmployees();
     
    //Sort all employees by first name
    employees.sort(Comparator.comparing(e -> e.getLastName()));
     
    //OR you can use below
    employees.sort(Comparator.comparing(Employee::getLastName));
     
    //Let's print the sorted list
    System.out.println(employees);

输出

[[9,Vishu,Bissi,33],
[6,Yash,Chopra,25],
[1,Lokesh,Gupta,32],
[4,James,Hedge,72],
[7,Karan,Johar,59],
[5,David,Kameron,19],
[10,Lokesh,Ramachandran,60],
[2,Aman,Sharma,28],
[8,Balaji,Subbu,88],
[3,Aakash,Yaadav,52]]
先根据firstName排序,再根据lastName排序

使用thenComparing()

List<Employee> employees  = getEmployees();
//Sorting on multiple fields; Group by.
Comparator<Employee> groupByComparator = Comparator.comparing(Employee::getFirstName)
                                                    .thenComparing(Employee::getLastName);
employees.sort(groupByComparator);
System.out.println(employees);
并行排序

只需要使用 parallelSort() 即可进行并行排序。

//Parallel Sorting
Employee[] employeesArray = employees.toArray(new Employee[employees.size()]);
//Parallel sorting
Arrays.parallelSort(employeesArray, groupByComparator);
System.out.println(employeesArray);

输出

[3,Aakash,Yaadav,52],
[2,Aman,Sharma,28],
[8,Balaji,Subbu,88],
[5,David,Kameron,19],
[4,James,Hedge,72],
[7,Karan,Johar,59],
[1,Lokesh,Gupta,32],         //These both employees are
[10,Lokesh,Ramachandran,60], //sorted on last name as well
[9,Vishu,Bissi,33],
[6,Yash,Chopra,25]
使用count() 和 counting() 统计数量

count()和counting()的区别是,count()是一个终端操作,对Stream计数并返回一个long,counting() 则是Collector的收集方法,用法区别如下:

使用count()

public static void main(String[] args)
{
    long count = Stream.of("how","to","do","in","java").count();
    System.out.printf("There are %d elements in the stream %n", count);
     
    count = IntStream.of(1,2,3,4,5,6,7,8,9).count();
    System.out.printf("There are %d elements in the stream %n", count);
     
    count = LongStream.of(1,2,3,4,5,6,7,8,9).filter(i -> i%2 == 0).count();
    System.out.printf("There are %d elements in the stream %n", count);
}

使用counting()

public static void main(String[] args)
{
    long count = Stream.of("how","to","do","in","java").collect(Collectors.counting());
    System.out.printf("There are %d elements in the stream %n", count);
     
    count = Stream.of(1,2,3,4,5,6,7,8,9).collect(Collectors.counting());
    System.out.printf("There are %d elements in the stream %n", count);
     
    count = Stream.of(1,2,3,4,5,6,7,8,9).filter(i -> i%2 == 0).collect(Collectors.counting());
    System.out.printf("There are %d elements in the stream %n", count);
}