Java 8使用多个comparators进行集合分组排序

位置:首页>文章>详情   分类: 教程分享 > Java教程   阅读(2120)   2023-03-28 11:29:14

1.模型类和多个比较器

我们的模型类Employee有4个简单的字段。
public class Employee implements Comparable<Employee> {

    private Integer id = -1;
    private Integer age = -1;
    private String firstName = null;
    private String lastName = null;

    public Employee(Integer id, String fName, String lName, Integer age) {
            this.id = id;
            this.firstName = fName;
            this.lastName = lName;
            this.age = age;
    }

    //Getters and Setters

    @Override
    public String toString() {
        return "\nEmployee [id=" + id + ", age=" + age + ", firstName=" + firstName + ", lastName=" + lastName + "]";
    }
}
多个比较器用于字段的名字,姓氏和年龄。
import java.util.Comparator;

public class FirstNameSorter implements Comparator<Employee> 
{
    public int compare(Employee o1, Employee o2) 
    {
        return o1.getFirstName().compareTo(o2.getFirstName());
    }
}

public class LastNameSorter implements Comparator<Employee> 
{
    public int compare(Employee o1, Employee o2) 
    {
        return o1.getLastName().compareTo(o2.getLastName());
    }
}

public class AgeSorter implements Comparator<Employee> 
{
    public int compare(Employee o1, Employee o2) 
    {
        return o1.getAge() - o2.getAge();
    }
}

2. Comparator.thenComparing()

使用内置的比较器链接支持,在Java 8中对列表进行排序非常容易。您通过实现Comparator接口创建了独立的字段排序器,并将它们链接到Collection.sort()方法中。
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class MultipleFieldSorter 
{
    public static void main(String[] args) 
    {
        List<Employee> list = Arrays.asList(new Employee(1, "A", "B", 34), 
                                        new Employee(4, "C", "D", 30), 
                                        new Employee(3, "B", "A", 31), 
                                        new Employee(2, "D", "C", 25));

        Collections.sort(list, new FirstNameSorter()
                                .thenComparing(new LastNameSorter())
                                .thenComparing(new AgeSorter()));

        System.out.println(list);
    }
}
输出:
[Employee [id=1, age=34, firstName=A, lastName=B], 
 Employee [id=3, age=31, firstName=B, lastName=A], 
 Employee [id=4, age=30, firstName=C, lastName=D], 
 Employee [id=2, age=25, firstName=D, lastName=C]]

3. CompareToBuilder

值按照它们附加到构建器的顺序进行比较。如果任何比较返回非零结果,则该值将是返回的结果,CompareToBuilder.toComparison()并且将跳过所有后续比较。

3.1。Apache常见的Lang3依赖

<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-lang3</artifactId>
	<version>3.7</version>
</dependency>

3.2。修改模型中的compareTo()方法

 
import org.apache.commons.lang3.builder.CompareToBuilder;
 
public class Employee implements Comparable<Employee> {
 
    private Integer id = -1;
    private Integer age = -1;
    private String firstName = null;
    private String lastName = null;
 
    public Employee(Integer id, String fName, String lName, Integer age) {
        this.id = id;
        this.firstName = fName;
        this.lastName = lName;
        this.age = age;
    }
 
    public int compareTo(Employee o) {
 
        if (o == null) {
            return -1;
        }
 
        CompareToBuilder buider = new CompareToBuilder();
 
        return buider
                .append(this.getFirstName(), o.getFirstName())
                .append(this.getLastName(), o.getLastName())
                .append(this.getAge(), o.getAge())
                .toComparison();
    }
 
    //getters and setters
}

3.3。排序列表

public class MultipleFieldSorter
{
    @SuppressWarnings("unchecked")
    public static void main(String[] args)
    {
        List<Employee> list = //list of employees;
 
        Collections.sort(list);
 
        System.out.println(list);
    }
}

3.4。CompareToBuilder与比较器接口

如果您不愿意修改Comparable界面,您仍然可以利用Comparator界面对列表CompareToBuilder进行排序
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
import org.apache.commons.lang3.builder.CompareToBuilder;
 
public class MultipleFieldSorter
{
    public static void main(String[] args)
    {
        List<Employee> list = Arrays.asList(new Employee(1, "A", "B", 34),
                                        new Employee(4, "C", "D", 30),
                                        new Employee(3, "B", "A", 31),
                                        new Employee(2, "D", "C", 25));
 
        Collections.sort(list, new Comparator<Employee>()
        {
            public int compare(Employee empOne, Employee empTwo)
            {
                return new CompareToBuilder()
                        .append(empOne.getFirstName(), empTwo.getFirstName())
                        .append(empOne.getLastName(), empTwo.getLastName())
                        .append(empOne.getAge(), empTwo.getAge())
                        .toComparison();
            }
        });
 
        System.out.println(list);   //Sorted list
    }
}

4. ComparisonChain

与Apache Common lang类似CompareToBuilder,Google guava库提供了有用的类ComparisonChain来排序对象列表

4.1。依赖

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>23.0</version>
</dependency>

4.2。比较链示例

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
import com.google.common.collect.ComparisonChain;
 
public class MultipleFieldSorter
{
    public static void main(String[] args)
    {
        List<Employee> list = Arrays.asList(new Employee(1, "A", "B", 34),
                                        new Employee(4, "C", "D", 30),
                                        new Employee(3, "B", "A", 31),
                                        new Employee(2, "D", "C", 25));
 
        Collections.sort(list, new Comparator<Employee>()
        {
            public int compare(Employee empOne, Employee empTwo)
            {
                return ComparisonChain.start()
                        .compare(empOne.getFirstName(), empTwo.getFirstName())
                        .compare(empOne.getLastName(), empTwo.getLastName())
                        .compare(empOne.getAge(), empTwo.getAge())
                        .result();
            }
        });
 
        System.out.println(list);
    }
}

5.链式比较器

这是使用多个比较器按多个字段对列表对象进行排序的最基本示例。在这种方法中,创建比较器有序列表并将其传递给迭代比较器并使用每个比较器对当前列表进行排序的方法。

5.1。组分拣机

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
 
public class GroupBySorter implements Comparator<Employee> {
 
    private List<Comparator<Employee>> listComparators;
 
    public GroupBySorter(Comparator<Employee>... comparators) {
        this.listComparators = Arrays.asList(comparators);
    }
 
    public int compare(Employee empOne, Employee empTwo) {
        for (Comparator<Employee> comparator : listComparators) {
            int result = comparator.compare(empOne, empTwo);
            if (result != 0) {
                return result;
            }
        }
        return 0;
    }
}
 

5.2。在列表中按排序应用组

现在我们可以使用上面的GroupBySorter方法对员工列表进行排序。下面的代码按以下顺序对员工列表进行排序:
  • 名字
  • 年龄
 
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
 
public class MultipleFieldSorter
{
    @SuppressWarnings("unchecked")
    public static void main(String[] args)
    {
        List<Employee> list = Arrays.asList(
                                new Employee(1, "A", "B", 34),
                                new Employee(4, "C", "D", 30),
                                new Employee(3, "B", "A", 31),
                                new Employee(2, "D", "C", 25));
 
        Collections.sort(list, new GroupBySorter(new FirstNameSorter(), new LastNameSorter(), new AgeSorter()));
 
        System.out.println(list);
    }
}
标签: java 集合排序 java8
地址:https://www.leftso.com/article/478.html

相关阅读

Java 8使用多个comparators进行集合分组排序
java 8 stream 多字段排序,本例子主要使用stream进行多个字段的排序,使用了 comparators和Comparator.thenComparing()方法。比较器之间返回一个...
java常见面试题之冒泡排序
简介本博文主要讲解在Java 8中 如何通过stream流的方式去重
Java EE 8 JSON Pointer讲解,Java EE 8包含JSON处理API的更新,并为最新的JSON标准提供最新的IEFT标准。
首先定义一个包含字符串日期的数据对象​public class ObjectDto implements Serializable { private static final long...
       快速排序算法是最常用的排序算法之一,尤其是对大型列表/数组进行排序。快速排序是一种分而治之算法,这意味着原始数组被分成两个数组,每个数组单独排序,然后合并排序输出以生成排序数组。平...
数组转集合List&lt;String&gtl; list=Arrays.asList("1","2");注意转换出来的List为Arrays内部类集合,与常规的ArrayList有区别,比如常...
javastreamList根据对象某个属性升序或降序排序代码参考;publicclassMyTests{@NoArgsConstructor@AllArgsConstructor@Datapu...
java8 Function 应用场景 --代码重构旧代码: import org.springframework.beans.BeanUtils; import java.util.func...