Java переопределяет метод compareTo для Arrays.sort()

Я пытаюсь переопределить метод compareTo, чтобы иметь возможность использовать Arrays.sort(), но когда я это делаю, кажется, что он не работает.

Я не получаю никаких ошибок, но у меня есть тестер, который проверяет и возвращает ошибку. Я должен сравнить «общие продажи» сравниваемых товаров.

Вот сравнение с методом, сравнивающим два элемента ItemSales.

    @Override
    public int compareTo(ItemSales item) {

        return Double.compare(item.totalSales, this.totalSales);
    }

Вот тестер тестирует это, кроме этого, конечно, есть еще много чего, но все остальное работает, даже clone().

ItemSales item = new ItemSales();
ItemSales newItem = new ItemSales(10.0, 50, 50.0);
ItemSales secondItem = (ItemSales) newItem.clone(); 
ItemSales[] myItems = { secondItem, item, newItem };

ItemSales[] myItems = { secondItem, item, newItem };

Arrays.sort(myItems);
if ( myItems[0].getTotalSales() == 860.0 && myItems[1].getTotalSales() == 870.0) {
    System.out.println("ItemSalesDemo.main()             - sorted, this is correct");
} else {
    System.out.println("ItemSalesDemo.main()             - ");
    System.out.println("ItemSalesDemo.main()             ------------------------");
    System.out.println("ItemSalesDemo.main()             -         Error        -");
    System.out.println("ItemSalesDemo.main()             ------------------------");
    System.out.println("ItemSalesDemo.main()             - item and newItem should have been equal");
    System.out.println("ItemSalesDemo.main()             - ");
    System.exit(-1);
} 

Как вы, возможно, знаете, я получаю сообщение об ошибке «элемент и новый элемент должны быть равны».


person user3593879    schedule 01.05.2014    source источник
comment
Вам следует прочитать документацию по интерфейсу Comparable, чтобы узнать, как работает compareTo.   -  person Pablo Lozano    schedule 01.05.2014
comment
форме javadoc a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. похоже, что вы пытаетесь использовать compareTo немного похоже на equals   -  person T.G    schedule 01.05.2014


Ответы (3)


Я думаю, что код будет работать лучше, если вы его измените:

@Override
public int compareTo(ItemSales item) {
    if (this.totalSales < item.totalSales) {
        return -1;
    }
    else if(this.totalSales > item.totalSales){
        return 1;
    }

    return 0;
}

Проблема с вашим предыдущим Double.compare() заключалась в том, что у вас были параметры в неправильном порядке, это должно было быть сравнение (это, элемент), а не наоборот

person Sara S    schedule 01.05.2014
comment
Примерно так и поступил бы Double.compare(totalSales, item.totalSales). - person Ted Hopp; 01.05.2014
comment
Верно, но легче ошибиться, когда вы смешиваете несколько функций вместе. Как и в этом случае, параметры были в неправильном порядке - person Sara S; 01.05.2014
comment
Спасибо, это сработало. Я делал это раньше, но у меня были цифры в обратном порядке. у меня было 1, где должно было быть -1 и -1, где должно было быть 1. Это было задолго до того, как я сделал все эти изменения. Но спасибо, это сработало. Я проголосую за лучший ответ через 2 минуты. - person user3593879; 01.05.2014
comment
Они не были в неправильном порядке, если OP пытался отсортировать по убыванию значения totalSales. - person Ted Hopp; 01.05.2014

Я вижу две возможные трудности в методе compareTo:

    if (this.totalSales != item.totalSales) {
        return 0;
    }

Обычно метод compareTo должен возвращать 0, если два объекта равны. Вы часто слышите фразу «compareTo должно быть согласовано с equals()», что означает, что equals() должно возвращать true, когда compareTo() возвращает 0, и equals() должно возвращать false, когда compareTo() возвращает что-то отличное от 0.

Как правило, compareTo должно возвращать -1, если this меньше, чем item (другой ItemSales, с которым вы сравниваете). compareTo должно возвращать 1, если это больше, чем другое item.

Вторая проблема заключается в том, что выглядит как потенциальный бесконечный цикл:

    return item.compareTo(this);

Мне больше нравится то, что вы прокомментировали:

    return Double.compare(item.totalSales, this.totalSales);

Это больше, чем я ожидал от метода сравнения.

person Jake Toronto    schedule 01.05.2014
comment
у меня есть метод, который просто возвращает return Double.compare(item.totalSales, this.totalSales); и еще ничего. - person user3593879; 01.05.2014

Измените свой код как

 @Override
    public int compareTo(ItemSales item) {

        return Double.compare( this.totalSales ,item.totalSales);
    }

В соответствии с вашим условием if вы исключаете в порядке возрастания. Поэтому измените параметры в Double.compare. Как говорили другие, сначала прочитайте спецификацию Comparable.

myItems[0].getTotalSales() == 860.0
person Mani    schedule 01.05.2014