【问题标题】:Having an error when using String in Comparator在比较器中使用字符串时出错
【发布时间】:2019-07-29 16:57:48
【问题描述】:

我正在尝试创建一个实现可比较的类。当所有类元素都是整数时,一切正常。当我使用 String 并使用 comparing 而不是 comparingInt 时,我收到以下错误。

  • Comparator 类型的泛型方法比较(函数)的类型参数数量不正确;它不能用参数参数化

  • myClass 类型未定义此处适用的 getFrom(T)

public class myClass implements Comparable<myClass> {
    @Column (name="From")
    private String from;
    @Column (name="To")
    private String to;
    @Column (name="With")
    private String with;
    @Column (name="amount")
    private int amount;

    // Setters, getters, constructor

    Comparator<myClass > comp = Comparator.<myClass>comparing(myClass::getFrom)
            .thenComparing(myClass::getTo)
            .thenComparing(myClass::getWith)
            .thenComparingInt(myClass::getAmount);
    @Override
    public int compareTo(myClass o) {
        return comp.compare(this, o);
    }
}

有人能指出我在这里可能缺少什么吗?

【问题讨论】:

  • 删除泛型类型,它应该可以工作或明确Comparator.&lt;myClass, String&gt;comparing...
  • @michalk 当我明确写它时,它起作用了。你能解释一下为什么会这样吗?

标签: java comparator comparable


【解决方案1】:

Comparator::comparing 是一种通用方法,它采用用于提取要比较的值的函数。您传递了对myClass::getFrom 方法的方法引用,该方法返回String 并将在myClass 类型对象上调用(通过Function::apply)。这就是为什么你必须传递泛型类型myClassString

但是您可以省略这些泛型类型,因为您将比较器分配给 Comparator&lt;myClass&gt; comp 变量,因此可以自动推断类型(也使用您使用的方法引用中的类型)。

进一步看一下Comparator::comparing(Function)方法的实现:

static <T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> var0) {
    Objects.requireNonNull(var0);
    return (Comparator)((Serializable)((var1x, var2x) -> {
        return ((Comparable)var0.apply(var1x)).compareTo(var0.apply(var2x));
    }));
}

这里T 将是myClassU 将是String。函数var0myClass 作为参数并返回String(因此对myClass::getFrom 的方法引用将在这里工作——通常它就像在myClass 对象上调用getFrom)。实际上,正如您所看到的,此方法将返回 Comparator 作为 lambda 函数,它将使用函数 var0var1xvar2x 中提取值(它们都是 myClass 类型)。对我来说,它看起来有点像一个闭包。

【讨论】:

    【解决方案2】:

    好的,这里有几件事。首先,这里的工作代码大部分只是删除了您提供的类型参数。

    您可以这样做,因为它们会被自动推断。您只需要在它们不可推断时明确地执行此操作(您的 IDE 会告诉您)。 Java 文档中散布着大量关于类型推断的信息。例如https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html

    import java.util.Comparator;
    
    public class MyClass implements Comparable<MyClass>{
        private String from;
        private String to;
    
        public String getFrom() { return from; }
        public String getTo() { return to; }
    
        Comparator<MyClass> comp = Comparator.comparing(MyClass::getFrom)
                .thenComparing(MyClass::getTo);
    
        @Override
        public int compareTo(MyClass o) {
            return comp.compare(this, o);
        }
    }
    

    其他一些总体上很有帮助或供将来参考的注释:

    • 类名中的首字母大写。
    • 尝试将您的代码精简为一个完整/可重现的示例。例如,这使用 2 个字段,这两个字段都存在并且可以粘贴到 IDE 中。第一个问题使用 4 个字段,其中大部分不存在。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-05
      • 2020-05-24
      相关资源
      最近更新 更多