4

我正在尝试通过编写自己的方法并使用可比较的实现来覆盖 java 中的默认 compareTo() 方法,但似乎 java 仍在使用默认方法。

我正在尝试按从 .dat 文件中获得的长度对字符串数组进行排序,但是它一直按字母顺序对其进行排序。如果有人能告诉我我做错了什么,我将不胜感激,因为我无法弄清楚为什么这不起作用。

谢谢

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

这是包含主要方法的类

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

4 回答 4

4

帮自己一个忙:每次重写一个方法时,@Override给它添加注解。如果您在覆盖该方法时出错,这将给您一个编译错误,这就是这里发生的事情。你实现它错误的,因为Comparable(“原始”形式Comparable<T>没有声明一个方法compareTo(String),它声明了一个方法compareTo(Object)

要使其按原样编译,您需要接受 aObject而不是 aString或实现Comparable<String>而不是Comparable.

但这在大多数情况下确实是不正确的,因为这样的比较不是对称的:您可以将 Word 与 String 进行比较,但不能将 String 与单词进行比较。

您很可能想要实施Comparable<Word>而不是Comparable接受 a Wordto compareTo()

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

请注意,只有当类型本质上是有序的(文档称之为“自然顺序”)时,这才Comparable非常合适,比如日期或数字。由于您实际上并没有按字母顺序比较两个单词(这将最接近字符串的自然顺序),因此这是使用外部比较器的更好候选者。

//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());
    }
}
于 2012-02-04T04:15:05.807 回答
2

Comparable已键入,但您使用的是原始类型。尝试这个:

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
    }
}
于 2012-02-04T04:16:24.860 回答
1

在此处检查 compareTo 方法的签名

它应该是int compareTo(Object o)

你给public int compareTo(String rhs)

您还可以@Override在方法中添加注释。如果您没有遵循正确的签名,它会通知您。

于 2012-02-04T04:14:22.667 回答
0

简短版本:您需要使用带有 Comparator 的 Arrays.sort 方法

长版:线

Arrays.sort(array);

sortByLength方法中不断调用compareTo它正在排序的对象的方法 - 这些对象是字符串!相反,你需要这条线

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

或者您可以创建一个单独的类来实现Comparator<String>并将其实例用作Arrays.sort.

于 2012-02-04T04:13:48.353 回答