【问题标题】:Sorting multiple attribute with Lambda Expressions使用 Lambda 表达式对多个属性进行排序
【发布时间】:2015-10-25 05:50:12
【问题描述】:

这是我的清单:

Name: Ben     || Age: 5 || Group: 1
Name: Andy    || Age: 6 || Group: 2
Name: Charlie || Age: 6 || Group: 2
Name: Ben     || Age: 5 || Group: 1
Name: Andy    || Age: 5 || Group: 2
Name: Charlie || Age: 5 || Group: 1

我想按Group 对列表进行排序,如果Group 相等,则按Age,如果Age 相等,则按Name。但到目前为止,我只能使用 Lambda 表达式按一个属性排序:

list.sort((Object o1, Object o2) -> o1.getGroup().compareTo(o2.getGroup()));

如果我尝试

o1.getGroup().compareTo(o2.getGroup()) && o1.getAge().compareTo(o2.getAge())

原来是错误...

【问题讨论】:

    标签: java lambda java-8


    【解决方案1】:

    把 lambda expression 改成 lambda {block},就不用指定参数类型了:

    list.sort((o1, o2) -> {
        int cmp = o1.getGroup().compareTo(o2.getGroup());
        if (cmp == 0)
            cmp = Integer.compare(o1.getAge(), o2.getAge());
        if (cmp == 0)
            cmp = o1.getName().compareTo(o2.getName());
        return cmp;
    });
    

    【讨论】:

    • 你是我今天的救世主 :) 谢谢
    • @HuyVo 在这里感谢某人的正确方式是为他们的回答点赞。
    • 如何使用原始数组(不是列表)来做到这一点?当使用int[] arrint[] arr 进行排序时,此语法似乎不起作用:Arrays.sort(arr, <multi-line lambda>);
    • @AnnaVopureta 没有按自定义顺序对原始数组进行排序的排序方法。 Java 运行时库仅具有按自然顺序对原始数组进行排序的方法。见:How to sort an array of ints using a custom comparator?
    【解决方案2】:

    您可以使用静态方法Comparator.comparing 基于返回可比较值的函数创建比较器。这样的比较器可以与其他比较器链接。

    假设您的类型称为 Person,您将:

    Comparator<Person> c = Comparator
            .comparing(p -> p.getGroup())
            .thenComparing(p -> p.getAge())
            .thenComparing(p -> p.getName())
    

    如果任何 getter 返回原始类型,则必须分别使用 - 例如 - comparingIntthenComparingInt。您还可以使用方法引用:

    Comparator<Person> c = Comparator
            .comparing(Person::getGroup)
            .thenComparing(Person::getAge)
            .thenComparing(Person::getName)
    

    但是......如果你的类有一个根据这些值的自然排序,你最好让它实现接口Comparable并在那里写比较逻辑:

    class Person implements Comparable<Person> {
        ...
        @Override
        public int compareTo(Person other) {
            int compare = Integer.compare(getGroup(), other.getGroup());
            if (compare == 0) {
                compare = Integer.compare(getAge(), other.getAge());
            }
            if (compare == 0) {
                compare = getName.compareTo(other.getName());
            }
            return compare;
        }
    }
    

    这段代码 sn-p 也可以用在 lambda 表达式中:

    list.sort((o1, o2) -> {
        int compare = Integer.compare(o1.getGroup(), o2.getGroup());
        if (compare == 0) {
            compare = Integer.compare(o1.getAge(), o2.getAge());
        }
        if (compare == 0) {
            compare = o1.getName.compareTo(o2.getName());
        }
        return compare;
    });
    

    【讨论】:

    • 使用 Integer.compare() 而不是减法,以防止在非常大的值上出现错误结果。
    • 您的第一个示例不起作用。编译器没有机会推断出pPerson...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    相关资源
    最近更新 更多