【问题标题】:Sort array of objects by one property of nested object按嵌套对象的一个​​属性对对象数组进行排序
【发布时间】:2023-01-06 23:12:35
【问题描述】:

我需要通过其对象属性之一的一个属性来比较一组对象。
我在做 :

List<Sell> collect = sells.stream()
        .sorted(Comparator.comparing(Sell::getClient.name, String::compareToIgnoreCase))
        .collect(Collectors.toList());

编译不了,有大神知道怎么弄吗?

谢谢。

【问题讨论】:

  • 错误是什么? Shell.getClient 是什么样子的?
  • 什么是销售、客户类定义?什么是您正在使用流的销售。提供完整代码。
  • 如果您想要不区分大小写的 Comparator,请使用 String.CASE_INSENSITIVE_ORDERString::compareToIgnoreCase 是一个返回 int 而不是 Comparator 的比较方法
  • 它只是说找不到 getClient.name。在 Sell 对象中,我有一个具有属性名称的 Client 对象。我觉得我不能将此方法与嵌套对象的属性一起使用。

标签: java arrays


【解决方案1】:

这是导致错误的代码部分

Sell::getClient.name

您可以创建对特定类型的任意对象的(静态或非静态)方法的引用。对 Sell 类型的任何对象的 getClient 方法的引用如下所示:

Sell::getClient

但是方法引用不是对象并且没有成员可以访问。使用此代码,您正在尝试访问引用的成员变量(并且不能)

Sell::getClient.name

此外,方法引用不是类,因此您无法从中获取其他方法引用。如果你尝试过,你就不能做这样的事情:

Sell::getClient::getName

@mlk 为您的特定情况提供了正确的语法:

  1. x -&gt; x.getClient().name
  2. Sell::getClientName(不必是静态方法)

【讨论】:

    【解决方案2】:

    为了访问嵌套属性并以相反的顺序排序,我这样做:

    Comparator<Sell> comparator = Comparator.comparing(h -> h.getAudit().getCreatedTs());
        sells.sort(comparator.reversed());
    

    【讨论】:

    • 这是让它对我有用的唯一方法:我试过Sell.sort((Comparator.comparing(x -&gt; x.getAudit().getCreatedTs()).reversed());但在反向方法上一直有错误
    【解决方案3】:

    我看不到您的代码,也看不到您遇到的错误。所以这是一个猜测。

    我相信你想要

    class Test {
    
        // I assume that Client looks like this.
        static class Client {
            public String name;
        }
    
        // And that Sell looks like this.
        // I'm sure your Client and Sell are bigger, but this is all 
        // that matters for now. 
        static class Sell {
            public Client getClient() { return null; }
        }
    
        public static void main (String[] args) throws java.lang.Exception
        {
            List<Sell> sells = new ArrayList<>();
            sells.stream().sorted(Comparator.comparing(x -> x.getClient().name, String::compareToIgnoreCase))
        }
    }
    

    你想在返回时调用一个方法,所以你需要创建一个匿名函数。

    您的另一个选择是:

    static class Sell {
        public String getClientName() { return null; }
    }
    // ...
            sells.stream().sorted(Comparator.comparing(Sell::getClientName, String::compareToIgnoreCase))
    

    【讨论】:

    • 我同意其中的大部分。但是如果像getClientName这样的方法可用,它就不必是静态的。根据tutorial,您可以获得“对特定类型的任意对象的实例方法的引用”
    • 啊。确定我的答案。