美文网首页
166. Java Lambda 表达式 - Comparato

166. Java Lambda 表达式 - Comparato

作者: Cache技术分享 | 来源:发表于2025-08-20 09:06 被阅读0次

166. Java Lambda 表达式 - Comparator 高级用法:自定义排序、工厂方法

在某些场景下,我们不希望用“自然顺序”来比较对象(比如按字母顺序、按数字从小到大等),而是想根据某个属性或特征进行比较。

✅ 示例:按字符串长度进行比较(非自然顺序)

Comparator<String> comparator =
    (s1, s2) -> Integer.compare(s1.length(), s2.length());

这是一个简单的比较器,比较的是字符串的“长度”,而不是它们的字典顺序(自然顺序)。换句话说,更短的字符串“更小”


🧠 将比较逻辑提取成Function

我们可以将字符串转换为长度的操作提取出来,使比较器逻辑更加清晰、可重用:

Function<String, Integer> toLength = String::length;

Comparator<String> comparator = (s1, s2) ->
    Integer.compare(toLength.apply(s1), toLength.apply(s2));

这时候,比较器的核心逻辑依赖的是一个函数 toLength,用于将 String 映射为 Integer(长度)。


⚒️ 使用 JDK 提供的工厂方法:Comparator.comparing

更进一步,我们可以用 JDK 中已经内置的 工厂方法 来简化这一过程:

Comparator<String> comparator = Comparator.comparing(String::length);

这行代码的含义是:

根据 String 的长度进行比较,因为 String::length 返回的是 Integer,而 IntegerComparable 类型,所以可以自然排序。


📦 工厂方法 Comparator.comparing 解读

static <T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor)
  • T: 要比较的对象类型。
  • U: 从对象中提取出来、用于比较的“关键字段”的类型,必须是 Comparable 的子类。
  • keyExtractor: 一个函数,用来提取比较所需的“关键字段”。

🧑💻 实战示例:对 User 列表按名称排序

假设有一个 User 类,并定义了 getName() 方法:

public class User {
    private String name;
    public String getName() { return name; }
    User(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "User{" + "name='" + name + '\'' + '}';
    }
}

你现在想按名称排序一个 User 列表,可以这样写:

List<User> users = ...;

Comparator<User> byName = Comparator.comparing(User::getName);
users.sort(byName);

也可以一步到位写成:

users.sort(Comparator.comparing(User::getName));

⚠️ 注意事项

  • comparing() 接收的函数,返回值必须是 Comparable 的子类(如 StringInteger 等)。
  • 若你想比较的字段不是 Comparable,可以使用重载版本,手动提供比较器。

相关文章

网友评论

      本文标题:166. Java Lambda 表达式 - Comparato

      本文链接:https://www.haomeiwen.com/subject/urtfajtx.html