简体   繁体   English

如何覆盖双打的 compareTo 方法?

[英]How to override compareTo method for doubles?

I'm currently having some trouble understanding how the compareTo method works for the Comparable class, and how to override it.我目前在理解 compareTo 方法如何适用于 Comparable class 以及如何覆盖它时遇到了一些麻烦。 I have array of pairs, each of which hold 2 double values, that I'm trying to sort.我有成对的数组,每一个都包含 2 个双精度值,我正在尝试对其进行排序。 This is what I tried:这是我尝试过的:

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

However, it doesn't compile and instead gives me this error:但是,它没有编译,而是给了我这个错误:

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

It worked when it was with integers, but not with doubles, why is that?它适用于整数,但不适用于双精度数,这是为什么呢? And how could I make it work with doubles?我怎样才能使它与双打一起工作? Thanks.谢谢。

compareTo has to return an int. compareTo 必须返回一个 int。 You can use Double.compare.您可以使用 Double.compare。

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

This can be generalised to below implementation to work with any Pair that whose T,V implements Comparable interface.这可以推广到下面的实现,以与 T,V 实现Comparable接口的任何 Pair 一起使用。 It is generally pointless to compare objects of classes that are not comparable (In a perfect world.).比较不可比较的类的对象通常是没有意义的(在完美的世界中。)。

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

This is better than your custom implementation because the classes that are Comparable will already be having a compareTo() method overridden.这比您的自定义实现要好,因为Comparable的类已经覆盖了 compareTo() 方法。 For your case, this will be using Double.compareTo() without even your knowledge:)对于您的情况,这将在您不知情的情况下使用 Double.compareTo() :)

For example:例如:

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

or (better variant):或(更好的变体):

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

If you want a general-purpose Pair class, see the correct Answer by Mohamed Anees A .如果您想要通用Pair class,请参阅Mohamed Anees A 的正确答案

If you want to go with your idea of a Pair class specifically for double primitive type, then consider the following code.如果您想 go 与您的想法Pair class 专门用于double基本类型,然后考虑以下代码。

record feature record功能

For brevity and simplicity, I use the new record feature in Java 16.为简洁起见,我使用 Java 16 中的新记录功能。

As a record , the constructor, getters, toString , and equals / hashCode are provided implicitly by the compiler.作为record ,构造函数、getter、 toStringequals / hashCode由编译器隐式提供。

Double.compare

For the comparison work, we simply delegate to the static Double.compare method that compares two double primitives.对于比较工作,我们简单地委托给 static Double.compare比较两个double原语的方法。 This technique was seen in the second variant of the Answer by yuri777 . yuri777 在 Answer的第二个变体中看到了这种技术。

Here is the complete Pair class.这是完整的Pair

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

Here is a complete example app to demonstrate.这是一个完整的示例应用程序来演示。

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

When run:运行时:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM