Lambda 实现超强排序
发布日期:2025-04-04 00:40:15 浏览次数:9 分类:精选文章

本文共 3137 字,大约阅读时间需要 10 分钟。

在系统开发过程中,数据排序是频繁遇到的场景。传统方法是通过存储系统的排序功能或在内存中直接排序。如今,我们将重点探讨第二种在内存中进行排序的方法,并结合Java8的新特性,详细阐述各种排序实现方式。

基础类定义

首先,我们定义了一个基础类 Student,该类将作为排序的模型。该类包含了两个字段:nameage,并提供了 equalshashCode 方法以确保对象的唯一性和一致性。

@Data@NoArgsConstructor@AllArgsConstructorpublic class Student {    private String name;    private int age;    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        Student student = (Student) o;        return age == student.age && Objects.equals(name, student.name);    }    @Override    public int hashCode() {        return Objects.hash(name, age);    }}

基于Comparator排序

在Java8之前,我们通常通过实现Comparator接口来排序数据。例如,以下是一个匿名内部类的实现:

Comparator
comparator = new Comparator
() { @Override public int compare(Student h1, Student h2) { return h1.getName().compareTo(h2.getName()); }};Collections.sort(students, comparator);

这种方法虽然简单,但在支持复杂排序逻辑时相对不够灵活。我们可以通过Lambda表达式将其简化:

Collections.sort(students, (h1, h2) -> h1.getName().compareTo(h2.getName()));

或者,对于更通用的使用,可以定义一个静态方法来实现特定的排序逻辑:

public static int compareByNameThenAge(Student s1, Student s2) {    if (s1.name.equals(s2.name)) {        return Integer.compare(s1.age, s2.age);    } else {        return s1.name.compareTo(s2.name);    }}Collections.sort(students, Student::compareByNameThenAge);

使用Comparator的comparing方法

从Java8开始,Comparator类增加了新的comparing方法,可以将传入的Function参数作为排序依据。例如,可以直接使用:

Comparator.comparing(Student::getName)

如果需要多级排序,可以使用thenComparing方法:

Comparator.comparing(Student::getName).thenComparing(Student::age)

这种方法简化了排序逻辑,同时非常直观。

多条件排序

有时候,我们需要对多个字段进行排序。例如,首先按名字排序,若名字相同,则按年龄排序。可以在Comparator中使用thenComparing方法实现:

Comparator.comparing(Student::getName).thenComparing(Student::age)

这种方法的灵活性和简洁性远远超过传统的匿名内部类实现。

在Stream中进行排序

在Java8引入的Stream API中,也支持排序操作。通过将集合流转换为排序流,再收集到结果集合中:

List
sortedStudents = students.stream() .sorted(comparator) .collect(Collectors.toList());

同样可以使用Lambda表达式:

students.stream()       .sorted((h1, h2) -> h1.getName().compareTo(h2.getName()))       .collect(Collectors.toList());

倒序排列

对于倒序排列,可以通过将比较逻辑取反实现。例如:

Comparator reverseComparator = (h1, h2) -> h2.getName().compareTo(h1.getName());Collections.sort(students, reverseComparator);

或者,直接使用Comparator.reversed()方法:

Collections.sort(students, Comparator.reverseOrder());

对于名字字段进行倒序排列:

Comparator.comparing(Student::getName, Comparator.reverseOrder());

处理null值

在实际应用中,列表中可能包含null值,或者排序的字段可能为null。为了安全排序,需要处理null值。Java8已提供了Comparator.nullsLastComparator.nullsFirst方法来处理这种情况。

例如,null值排在结尾:

Comparator.nullsLast(Comparator.comparing(Student::getName))

null值排在开头:

Comparator.nullsFirst(Comparator.comparing(Student::getName))

为了处理排序条件字段为null的情况,可以使用双重Comparator.nullsLast

Comparator.nullsLast(    Comparator.nullsLast(        Comparator.comparing(Student::getName, Comparator.nullsLast(Comparator.naturalOrder()))    ))

这种方法允许我们在复杂场景下安全排序数据。

总结

通过对Java8中内存排序的全面探讨,我们掌握了多种排序实现方式。从传统的Comparator接口到现代的Lambda表达式,再到StreamAPI和倒序排列,以及处理null值的方法,这些方法为我们提供了灵活高效的数据排序工具。无论是基础场景还是复杂逻辑,这些方法都能满足我们的需求。

上一篇:Lambda 表达式(使用前提、“类型推断”、作用、优缺点、Lambda还能省略的情况)【java8新特性------Lambda 表达式】
下一篇:lambda 与列表理解性能

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2025年04月28日 18时57分44秒