2015-08-14 2 views
0

У меня есть вопрос относительно интерфейса компаратора. Ниже моего класса реализуется интерфейс для сортировки строк по длине вместо сортировки по умолчанию, которая сортируется по значению символа.Интерфейс компаратора Java и инициализационный компаратор

После переопределения сравнения по умолчанию я использовал Arrays.sort() для сортировки моего массива строк. Несмотря на то, что я переопределил метод по умолчанию, если я использую Arrays.sort, он вызывает сравнение по умолчанию вместо моего переопределенного метода. Это потому, что я прямо называю метод суперкласса?

Другой вопрос - инициализация самого интерфейса. Я знаю, что вы не можете инициализировать интерфейс и вместо этого инициализировать объект класса (который реализует указанный интерфейс), чтобы ссылаться на методы, доступные для интерфейса. В этом случае, когда я инициализирую компаратор, Arrays.sort(strArr, new Ideone()); сортировка работает правильно. Как метод знает, что я передаю ему компаратор? Я только инициализировал объект класса и не вызывал метод compare(ob1, ob2) явно.

Даже если я делаю Comparator x = new Ideone();, как объект класса сводится к объекту компаратора? Любое объяснение этому было бы полезно.

import java.util.*; 
import java.lang.*; 
import java.io.*; 

/* Name of the class has to be "Main" only if the class is public. */ 
class Ideone implements Comparator 
{ 

    static String ThirdGreatest(String[] strArr) 
    { 
     Arrays.sort(strArr); 
     //Arrays.sort(strArr, new Ideone()); 
     for(String x: strArr) 
      { 
      System.out.println(x); 
      } 
     return strArr[strArr.length-3]; 
    } 

    @Override 
    public int compare(Object s1, Object s2) 
    { 
     return (s1.toString().length() - s2.toString().length()); 
    } 

    public static void main (String[] args) throws java.lang.Exception 
    { 
     String[] myarr = {"coder","byte","code", "asfasfasfasf"}; 
     System.out.println(ThirdGreatest(myarr)); 
    } 
} 
+1

Вы не сказали, что хотите использовать ваш компаратор. Это также странный способ настройки компаратора. См. Http://stackoverflow.com/questions/8632857/sorting-string-lengths-using-comparator для примера. – jarmod

+0

Возможно, вы захотите проверить, что 'strArr' имеет как минимум 3 элемента. –

+0

Я рекомендую отделить реализацию компаратора от вашего основного класса. Легче понять, когда компаратор является только компаратором и в нем нет посторонних статических методов. – dsh

ответ

5

Даже если я переопределил метод по умолчанию, если я использую Arrays.sort, он вызывает сравнение по умолчанию вместо моего переопределенного метода. Это потому, что я прямо называю метод суперкласса?

Нет, это потому, что в этом примере вы дали, вы не передаете в компараторе - поэтому метод sort не имеет никакого способа знать, что вы пытаетесь использовать пользовательские сравнения.

В этом случае, когда я инициализирую компаратор, Arrays.sort(strArr, new Ideone()); сортировка работает правильно. Как метод знает, что я передаю ему компаратор?

Потому что вы вызываете перегрузку, принимающую компаратор.Там является только one overload с двумя параметрами:

public static <T> void sort(T[] a, Comparator<? super T> c) 

Теперь по общему признанию, это было бы лучше, если бы вы реализовали Comparator<String> вместо сырого Comparator типа, но он по-прежнему в силе.

Я только инициализировал объект класса и не вызывал метод compare(ob1, ob2) явно.

Действительно - вы не должны вызывать compare. Это задача метода sort. Вы передаете компаратор таким образом, чтобы он мог позвонить compare.

+0

Это помогает! Я не понимал, что я только переопределяю параметр 2 и ожидаю, что он будет автоматически вызван вызовом сортировки по умолчанию. – Help123

+0

@ Help123: Я не знаю, что вы подразумеваете под «только переопределением параметра 2» ... –

+0

Извините, что сказал, что я не понял после переопределения сравнения, мне пришлось пройти в компараторе, чтобы он использовал мой пользовательский метод сравнения. Я был в предположении, что он будет вызван по умолчанию, как только я переопределю его в своем классе. Я должен прочитать эту тему. – Help123

2

Я думаю, что проблема здесь в том, что, когда вы создали компаратор для использования в Arrays.sort, вы на самом деле не сказали Arrays.sort использовать его. По умолчанию, если вы только что сказали

Arrays.sort(strArr); 

затем the strings will be sorted using the default comparator. Рассказывать алгоритм сортировки, чтобы использовать свой собственный компаратор, you need to pass it as a second argument to the method:

Arrays.sort(strArr, new Ideone()); 

Попробуйте увидеть, если это фиксирует вещи. Как забавный тест, поставьте оператор println в своей функции сравнения, чтобы увидеть, можете ли вы посмотреть, как он вызван.

При этом довольно необычно реализовать компаратор таким образом. Более распространенный маршрут будет делать что-то вроде этого:

Arrays.sort(strArr, new Comparator<String>() { 
    public int compare(Object s1, Object s2) { 
     return (s1.toString().length() - s2.toString().length()); 
    } 
}); 

Теперь вам не нужно реализовывать compare на Ideone класса, что делает более ясным, что (1) он не будет вызываться автоматически, и (2) вам нужно только это для этого одного этапа сортировки.

+0

Это определенно помогает. Я предполагаю, что вы используете анонимный класс для создания компаратора, чтобы передать его в метод сортировки. – Help123

+0

@ Help123 Да, это именно оно. Вообще говоря, если вам нужен разовый компаратор, это очень хороший способ сделать это! – templatetypedef

0
Arrays.sort(strArr) 

Этот тип массива строковых объектов используется с помощью Java-компаратора. Вы не сказали своей функции сортировки использовать функцию сравнения, которую вы создали. Должна быть ссылка на ваш класс Ideone.

Comparator x = new Ideone(); 

Поскольку Ideone() реализует Comparator, он должен реализовать все методы в интерфейсе Comparator. Переменная x будет использовать метод сравнения класса Ideone, поскольку он переопределяется. Тем не менее, если вы попытаетесь использовать метод класса Ideone, который отсутствует в классе Comparator, вы выкинете исключение.

Смежные вопросы