简体   繁体   English

compareTo()方法在使用Comparable接口时不会覆盖默认方法

[英]compareTo() method is not overriding default method when using Comparable interface

I am trying to overwrite the default compareTo() method in java by writing my own and using implements comparable, however it seems that java is still using the default method. 我试图通过编写我自己的和使用可比较的实现覆盖java中的默认compareTo()方法,但似乎java仍然使用默认方法。

I am trying to sort an array of Strings by length that I get from a .dat file, however it keeps sorting it by alphabetic order instead. 我试图按照从.dat文件中获取的字符串数组来排序,但是它会按字母顺序对其进行排序。 I would appreciate it if someone could tell me what I am doing wrong as I cannot figure out why this does not work. 如果有人能告诉我我做错了什么我会很感激,因为我无法弄清楚为什么这不起作用。

Thanks 谢谢

import static java.lang.System.*;
import java.util.Arrays;

public class Word implements Comparable
{
private String word;
private String[] array;

public Word()
{
    word = "";
}

public Word(String s)
{
    word = s;
}

public void setWord(String s)
{
    word = s;
}

public int compareTo(String rhs)
{
    String temp = (String)rhs;
    if(word.length() > temp.length())
        return 1;
    else if(word.length() < temp.length())
        return -1;

    return 0;
}

public void setSize(int size)
{
    array = new String[size];
}

public void add(int spot, String other)
{
    array[spot] = other;
}

public String[] sortByLength()
{
    Arrays.sort(array);
    return array;
}
public String toString()
{
    return Arrays.toString(array);
}
}

Here is the class that contains the main method 这是包含main方法的类

import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.Arrays;
import static java.lang.System.*;

public class Lab18d
{
public static void main( String args[] ) throws IOException
{
    Scanner file = new Scanner(new File("lab18d.dat"));

    int size = file.nextInt();
    file.nextLine();
    Word test = new Word();
    test.setSize(size);
    String word = "";

    for(int i = 0; i < size; i++)
    {
        word = file.next();
        test.setWord(word);
        test.add(i, word);
    }
    test.sortByLength();
    System.out.println(test);
}
}

Do yourself a favour: every time you override a method, add the @Override annotation to it. 帮自己一个忙:每次覆盖一个方法时,都要为它添加@Override注释。 This will give you a compile error if you make a mistake in overriding the method, which is what is happening here. 如果你在覆盖方法时出错,这将给你一个编译错误,这就是这里发生的事情。 You are implementing it wrong, as Comparable (the "raw" form of Comparable<T> does not declare a method compareTo(String) , it declares a method compareTo(Object) . 实现它错误的,因为Comparable (“原始”的形式Comparable<T>不声明的方法compareTo(String) ,它声明了一个方法compareTo(Object)

To get it to compile as is, you would need to accept an Object instead of a String or implement Comparable<String> instead of Comparable . 要使其按原样编译,您需要接受Object而不是String或实现Comparable<String>而不是Comparable

But that would really be incorrect in most cases, because such a comparison is not symmetric: you can compare a Word to a String but not a String to a word. 但是在大多数情况下这确实是不正确的,因为这种比较不是对称的:你可以将Word与String进行比较,但不能将String与单词进行比较。

Most likely you want to implement Comparable<Word> instead of Comparable and accept a Word to compareTo() . 您很可能希望实现Comparable<Word>而不是Comparable并接受Word to compareTo()

@Override
public int compareTo(Word other)
{
    String temp = other.word;
    //...
}

Note though that Comparable is only a really good fit when a type is intrinsically ordered (what the docs call a "natural order") like dates or numbers. 请注意,当一个类型本质上被排序(文档称之为“自然顺序”)时, Comparable仅仅是一个非常合适的日期或数字。 Since you are not actually comparing the two words alphabetically (which would be the closest to a String's natural order) this is a better candidate for using an external comparator . 由于您实际上并没有按字母顺序比较这两个单词(这将是最接近String的自然顺序),因此这是使用外部比较器的更好选择。

//since Word.word is a private member, this either needs to be nested inside of Word
//or Word.word would need to be given an accessor method
public static class LengthComparator implements Comparator<Word> {
    @Override
    public int compare(Word word1, Word word2) {
        return Integer.valueOf(word1.word.length()).compareTo(word2.word.length());
    }
}

Comparable is typed, but you're using the raw type. Comparable是键入的,但您使用的是原始类型。 Try this: 试试这个:

public class Word implements Comparable<Word> { // Note: typing of Comparable
    ...

    public int compareTo(Word rhs) { // Note: parameter is typed
        String temp = rhs.word;
        return word.length() - temp.length(); // Note: Simplification of code
    }
}

Check the signature of compareTo method here 这里检查compareTo方法的签名

It should be int compareTo(Object o) 它应该是int compareTo(Object o)

and you are giving public int compareTo(String rhs) 并且你给public int compareTo(String rhs)

You can also add @Override annotation to your method. 您还可以将@Override注释添加到方法中。 It will let you know if you are not following proper signature. 如果您没有遵循正确的签名,它会通知您。

The short version: You need to use the Arrays.sort method taking a Comparator instead. 简短版本:你需要使用Arrays.sort方法来代替比较器

The long version: The line 长版本:该行

Arrays.sort(array);

in the sortByLength method keeps calling the compareTo methods on the objects it's sorting - and those objects are strings! sortByLength方法中,它一直在对它正在排序的对象调用compareTo方法 - 这些对象都是字符串! Instead, you need the line 相反,你需要这条线

Arrays.sort(array, new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        if (s1.length() > s2.length())
            return 1;
        if (s1.length() < s2.length())
            return -1;

        return 0;
    }
});

or you can create a separate class implementing Comparator<String> and use an instance of that as the second argument to Arrays.sort . 或者您可以创建一个单独的类来实现Comparator<String>并使用它的实例作为Arrays.sort的第二个参数。

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

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