метод compareTo () не переопределяет метод по умолчанию при использовании интерфейса Comparable - PullRequest
4 голосов
/ 04 февраля 2012

Я пытаюсь переписать метод сравнения по умолчанию в java, написав свой собственный и используя сопоставимые орудия, однако кажется, что 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);
}
}

Вот класс, который содержит метод 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);
}
}

Ответы [ 4 ]

4 голосов
/ 04 февраля 2012

Сделайте себе одолжение: каждый раз, когда вы переопределяете метод, добавляйте к нему аннотацию @Override. Это даст вам ошибку компиляции, если вы допустите ошибку при переопределении метода, что и происходит здесь. Вы неправильно его реализуете, поскольку Comparable («необработанная» форма Comparable<T> не объявляет метод compareTo(String), она объявляет метод compareTo(Object).

Чтобы компилировать его как есть, вам нужно будет принять Object вместо String или реализовать Comparable<String> вместо Comparable.

Но это действительно было бы неправильно в большинстве случаев, потому что такое сравнение не симметрично: вы можете сравнить слово со строкой, а не строку со словом.

Скорее всего, вы хотите реализовать Comparable<Word> вместо Comparable и принять от Word до 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());
    }
}
2 голосов
/ 04 февраля 2012

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
    }
}
1 голос
/ 04 февраля 2012

Проверка подписи метода сравнения здесь

Это должно быть int compareTo(Object o)

и вы даете public int compareTo(String rhs)

Вы также можете добавить аннотацию @Override к своему методу. Он сообщит вам, если вы не следуете правильной подписи.

0 голосов
/ 04 февраля 2012

Краткая версия: вам нужно использовать метод 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.

...