我们如何在 Comparator.comparing 中传递变量字段/方法名称

dog*_*ish 3 java java-8

我有Report {String name, Date date, int score }课。我希望能够使用新的 java 8 语法对任何成员变量的报告列表进行排序

所以java 8提供了这个新的

list.sort(Comparator.comparing(report -> report.name)) 
Run Code Online (Sandbox Code Playgroud)

按名称对列表进行排序。

可以说,我想为此方法提供一个变量字段名称,而不是名称,例如。就像是

list.sort(Comparator.comparing(report -> report.anyField))
Run Code Online (Sandbox Code Playgroud)

其中anyField 可以是名称、日期或分数。我如何实现这种行为。

Hol*_*ger 5

只需为每个属性创建一个比较器即可。

\n\n
static Map<String,Comparator<Report>> ORDER;\nstatic {\n    HashMap<String,Comparator<Report>> m=new HashMap<>();\n    m.put("name", Comparator.comparing(r -> r.name));\n    m.put("date", Comparator.comparing(r -> r.date));\n    m.put("score", Comparator.comparingInt(r -> r.score));\n    ORDER=Collections.unmodifiableMap(m);\n}\npublic static void sort(List<Report> list, String order) {\n    Comparator<Report> c=ORDER.get(order);\n    if(c==null) throw new IllegalArgumentException(order);\n    list.sort(c);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以考虑使用enum作为替代String,这消除了提供不存在的属性名称的可能性:

\n\n
enum ReportOrder {\n    NAME(Comparator.comparing(r -> r.name)),\n    DATE(Comparator.comparing(r -> r.date)),\n    SCORE(Comparator.comparingInt(r -> r.score));\n\n    private Comparator<Report> cmp;\n    private ReportOrder(Comparator<Report> c) { cmp=c; }\n\n    public void sort(List<Report> list) {\n        list.sort(cmp);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在你可以说,例如ReportOrder.NAME.sort(list);。当然,其他委托方式也可以:

\n\n
public static void sort(List<Report> list, ReportOrder o) {\n    list.sort(o.cmp);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

\xc2\xa0

\n\n
sort(list, ReportOrder.DATE);\n
Run Code Online (Sandbox Code Playgroud)\n