【问题标题】:Using a lambda expression for a comparable使用 lambda 表达式进行比较
【发布时间】:2021-04-10 00:45:07
【问题描述】:
import java.util.*;  
import java.io.*; 

class Simpson implements Comparable<Simpson> {
    String name;

    Simpson(String name) {
        this.name = name;
    }

    @Override
    ( simpson) -> {
        return this.name.compareTo(simpson.name);
    }
}

public class Main {

     public static void main(String... sortingWithList) {
        List<Simpson> simpsons = new ArrayList<>();
        simpsons.add(new Simpson("Homer "));
        simpsons.add(new Simpson("Marge "));
        simpsons.add(new Simpson("Bart "));
        simpsons.add(new Simpson("Lisa "));

        Collections.sort(simpsons);
        simpsons.stream().map(s -> s.name).forEach(System.out::print);

我想使用 lambda 表达式进行比较,但出现错误。

【问题讨论】:

  • 为什么要在一个类上实现 lambda?
  • 您的代码似乎不完整。我建议进行编辑以正确格式化它。请告诉我们您遇到了哪个错误(edit 并将错误输出作为文本发布)。您只想按字母顺序对名称进行排序吗?
  • 有一个 JEP 草案:简明方法体。 openjdk.java.net/jeps/8209434 不知道整合有没有进展。同时,只需使用标准的公共方法。

标签: java lambda comparable


【解决方案1】:

用这个代替Collections.sort:

simpsons.sort((s1, s2) -> s1.compareToIgnoreCase(s2));

【讨论】:

  • 集合上的sort 是持久的(它会修改它们)还是只返回一个排序的集合(不可变)?作为学习者,我会问?
【解决方案2】:

查看接口 Comparable&lt;T&gt; 的 Java Doc。

它提供了一种将此对象与另一个相同类型的对象(在参数o 中传递)进行比较的方法(在您的情况下:T 是Simpson

int compareTo(T o)

此外,您的 name 属性已经具有可比性,因为 String 类型也是如此,implements this interface 也是如此。所以你可以简单地委托(你已经做得很好了)。

假设错误

更正方法签名,它目前不完整,可能是编译错误的原因:

@Override (辛普森) -> { 返回 this.name.compareTo(simpson.name); . }

修复问题

为方法提供与接口规定相同的名称返回类型参数

public int compareTo(Simpson o) {
    if (o == null || this.name == null) return -1; // could adjust to your needs to avoid NPE
    return this.name.compareTo( o.name );
}

最重要的是:由于要从外部调用接口,所以实现的方法必须是public

只需 lambda

或者只是按照上一个答案中的建议使用适当的 lambda 表达式 流式传输 ?

simpsons.stream()
    .map(s -> s.name) // map serves like delegation to name
    .sorted((s1, s2) -> s1.compareToIgnoreCase(s2)) // sort previous with current element, here: names alphabetically
    .forEach(System.out::print);

在流中排序时的区别:

  • 使用sorted(),而不是sort() 之类的集合
  • 您可以将Comparator 指定为函数式lambda 表达式
  • 您也可以按自然顺序进行排序(如下问题所示)

还有另一种更简单的按字典顺序对字符串进行排序的方法:

Java 8 Stream sorting List of String

比较器和自然顺序

您还可以将两者结合起来: (1) 可比接口,由 Simpson 实现 (2) 函数式流,按比较器或 lambda 表达式排序(视情况而定)。

simpsons.stream() 
   .sorted((s1, s2) -> s1.compareTo(s2)) // sort previous with current Simpson ! explicit comparator passed as lambda
   .forEach( s -> System.out.println(s.name) );  // print name of Simpson in new line

在简单的情况下,你不需要?

或者您可以使用智能排序和!通过替换为.sorted() 隐式重用现有的自然顺序。 还可以尝试开箱即用的情况(没有任何 compareTo ⁉️):

class Simpson {
    String name;

    Simpson(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }

}

// main omitted, just the usage example:
simpsons.stream().sorted().forEach(System.out::println );

如果没有可比性,自然排序会回退到使用toString。同样的方式打印使用toString

排序是否正确,打印是否吸引人❔

【讨论】:

  • 我是 lambda 表达式的新手。由于 lambda 表达式使用的是函数式接口,因此可比较也是一个函数式接口。那么我如何在这里使用 lambda 表达式。就像我们可以用于比较器接口一样。
  • @SonamBanerjee 没问题,我已经认出了。只要您的Simpson claas 正确Comparable,您就可以在Simpson 对象流上使用sorted()。然后他们“遵循”自然顺序:意味着 -able 接口默认用作 -ator 功能。见Comparator tutorial
【解决方案3】:

我认为问题在于您正在实现 Comparable,这意味着它实现了 compareTo 方法。

import java.util.*;  
import java.io.*; 

class Simpson implements Comparable<Simpson> {
    String name;

    Simpson(String name) {
        this.name = name;
    }

    @Override
    int compareTo(Simpson other){
        return this.name.compareTo(other.name);
    }
}

public class Main {

     public static void main(String... sortingWithList) {
        List<Simpson> simpsons = new ArrayList<>();
        simpsons.add(new Simpson("Homer "));
        simpsons.add(new Simpson("Marge "));
        simpsons.add(new Simpson("Bart "));
        simpsons.add(new Simpson("Lisa "));

        Collections.sort(simpsons);
        simpsons.stream().map(s -> s.name).forEach(System.out::print);

     }

}

【讨论】:

  • 是的 OP 试图实现,但显然忘记了名称、返回类型、可见性。我可以提醒您,问题代码和您的代码都不会运行(语法)。
猜你喜欢
  • 2020-02-08
  • 1970-01-01
  • 2010-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-24
  • 2012-09-11
  • 2022-08-13
相关资源
最近更新 更多