如何为双打覆盖 compareTo 方法?

How to override compareTo method for doubles?

我目前在理解 compareTo 方法如何用于 Comparable class 以及如何覆盖它时遇到一些问题。我有一对数组,每个数组都有 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 必须 return 一个整数。您可以使用 Double.compare.

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

例如:

   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);
        }
    }

这可以概括为以下实现,以与任何其 T,V 实现 Comparable 接口的 Pair 一起工作。比较 类 不可比较的对象通常毫无意义(在完美世界中!)。

public class GenComparableWhosebug {
  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() :)

如果你想要一个通用的 Pair class,请参阅正确的

如果你想按照你的想法 Pair class 专门用于 double 基本类型,请考虑以下代码。

record 特征

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

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

Double.compare

对于比较工作,我们简单地委托给静态Double.compare method that compares two double primitives. This technique was seen in the second variant of the

这里是完整的 Pair class.

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]]