【问题标题】:How to override compareTo method for doubles?如何覆盖双打的 compareTo 方法?
【发布时间】:2021-04-25 06:24:53
【问题描述】:

我目前在理解 compareTo 方法如何用于 Comparable 类以及如何覆盖它时遇到了一些麻烦。我有成对的数组,每一个都包含 2 个双精度值,我正在尝试对其进行排序。这是我尝试过的:

static class Pair implements Comparable<Pair>
{
    double x;
    double y;
    Pair(double x, double y)
    {
        this.x = x;
        this.y = y;
    }
    public double compareTo(Pair other)
    {
        return y - other.y;
    }
}

但是,它没有编译,而是给了我这个错误:

Main.java:5: error: Pair is not abstract and does not override abstract method compareTo(Pair) in Comparable
    static class Pair implements Comparable<Pair>
           ^
Main.java:14: error: compareTo(Pair) in Pair cannot implement compareTo(T) in Comparable
        public double compareTo(Pair other)
                      ^
  return type double is not compatible with int
  where T is a type-variable:
    T extends Object declared in interface Comparable
2 errors

它适用于整数,但不适用于双精度数,这是为什么呢?我怎样才能使它与双打一起工作?谢谢。

【问题讨论】:

  • compareTo returns an int,不是双重的。错误中也有说明。
  • 不需要给Pair&lt;double,double&gt;指定泛型参数吗?
  • 如何修改以使其适用于双打?
  • @JuanMendes 给定的类Pair 没有任何泛型类型参数;如果有,double 将不是与它们一起使用的有效类型,因为它是原始类型。
  • @khelwood 我一定在想一个(不同的对)[docs.oracle.com/javase/9/docs/api/javafx/util/Pair.html]?我认为他们会自动装箱:p

标签: java sorting comparable compareto


【解决方案1】:

这可以推广到下面的实现以与任何 T,V 实现 Comparable 接口的 Pair 一起使用。比较不可比较的类的对象通常是没有意义的(在一个完美的世界中!)。

public class GenComparableStackOverflow {
  public static void main(String[] args){
    Pair<Double,Double> pair1 = new Pair<>(2.0,2.0);
    Pair<Double,Double> pair2 = new Pair<>(4.0,1.0);
    Stream.of(pair1,pair2).sorted().forEach(System.out::println); //Uses compareTo
  }

}

class Pair<T extends Comparable<T>,V extends Comparable<V>> implements Comparable<Pair<T,V>> {
  T x;
  V y;

  Pair(T x, V y) {
    this.x = x;
    this.y = y;
  }

  @Override
  public String toString() {
    return "Pair{" +
        "x=" + x +
        ", y=" + y +
        '}';
  }

  @Override
  public int compareTo(Pair<T, V> o) {
    return this.y.compareTo(o.y);
  }
}

这比您的自定义实现要好,因为Comparable 的类已经覆盖了 compareTo() 方法。对于您的情况,这将在您不知情的情况下使用 Double.compareTo() :)

【讨论】:

    【解决方案2】:

    compareTo 必须返回一个 int。您可以使用 Double.compare。

    public int compareTo(Pair other) {
        return Double.compare(y, other.y);
    }
    

    【讨论】:

    • 这是正确的,但如果它有更多的细节会是一个更好的答案。
    • 你是对的;我的时间很短。最后,我至少添加了代码 sn-p 以明确我的意思。
    【解决方案3】:

    例如:

       static class Pair implements Comparable<Pair> {
    
            double x;
            double y;
    
            Pair(double x, double y) {
                this.x = x;
                this.y = y;
            }
    
            public int compareTo(Pair other) {
                if (y > other.y) {
                    return 1;
                } else if(y<other.y)  {
                    return -1;
                } else {
                    return 0;
                }
            }
        }
    

    或(更好的变体):

        static class Pair implements Comparable<Pair> {
    
            double x;
            double y;
    
            Pair(double x, double y) {
                this.x = x;
                this.y = y;
            }
    
            public int compareTo(Pair other) {
                return Double.compare(this.y, other.y);
            }
        }
    

    【讨论】:

    • 永远不会返回零的 compareTo 方法是错误的。只需使用Double.compare 而不是自己动手。
    • 我只是展示了这个例子。当然,比较的逻辑可能更困难,并且也包括字段 x
    • 人们可能会直接从已接受的答案中复制代码。如果您的代码不完全正确,请编辑您的答案并说出来,或者修复它以使其正确。
    • 我为相等字段 y 添加了return 0
    • 使用Double.compare 的一个很好的理由是它可以处理边缘情况(特别是NaN)。您的代码会说 10 和 NaN 是“相等的”。
    【解决方案4】:

    如果您想要一个通用的Pair 类,请查看正确的Answer by Mohamed Anees A

    如果您想采用专门针对 double 原始类型的 Pair 类的想法,请考虑以下代码。

    record 功能

    为简洁起见,我使用 Java 16 中的新 record 功能。

    作为record,构造函数、getter、toStringequals/hashCode 由编译器隐式提供。

    Double.compare

    对于比较工作,我们简单地委托给比较两个double 原语的静态Double.compare 方法。这种技术出现在Answer by yuri777 的第二个变种中。

    这是完整的Pair 类。

    record Pair(double x , double y) implements Comparable < Pair >
    {
        @Override
        public int compareTo ( Pair o )
        {
            return Double.compare( this.y , o.y );
        }
    }
    

    这是一个完整的示例应用程序来演示。

    package work.basil.example;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class App2
    {
        public static void main ( String[] args )
        {
            App2 app = new App2();
            app.demo();
        }
    
        private void demo ( )
        {
            List < Pair > pairs = new ArrayList <>( 3 );
            pairs.add( new Pair( 2.1D , 3.1D ) );
            pairs.add( new Pair( 4D , 3D ) );
            pairs.add( new Pair( 1.1D , 1.1D ) );
            System.out.println( "pairs = " + pairs );
    
            Collections.sort( pairs );
            System.out.println( "pairs = " + pairs );
        }
    
        record Pair(double x , double y) implements Comparable < Pair >
        {
            @Override
            public int compareTo ( Pair o )
            {
                return Double.compare( this.y , o.y );
            }
        }
    }
    

    运行时:

    pairs = [Pair[x=2.1, y=3.1], Pair[x=4.0, y=3.0], Pair[x=1.1, y=1.1]]
    pairs = [Pair[x=1.1, y=1.1], Pair[x=4.0, y=3.0], Pair[x=2.1, y=3.1]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-02
      • 1970-01-01
      • 2011-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多