Как использовать интерфейс Comparator

Я новичок в java, и я не понимаю, как использовать интерфейс компаратора. У меня есть ArrayList of Item в классе Inventory и Item. В классе Item я написал:

public class Item implements Comparator<Item> {
    //stuff
    ...
    @Override
    public int compare(Item a, Item b) {
        if (a.getID().compareToIgnoreCase(b.getID())>0)
            return 1;
        else if (a.getID().compareToIgnoreCase(b.getID())<0)
            return -1;
        else
            return 0;
    }
}

Метод getID() просто дает идентификатор, который я должен использовать для алфавита элементов. Я не уверен, что это правильно, это заставило меня добавить аннотацию @Override, я не уверен, почему. Также я написал интерфейс, который просто говорит:

 public interface Comparator<Item>
{
    int compare(Item a, Item b);
}

Я не уверен в этом. Также как я могу реализовать этот метод для сортировки arraylist, созданного в классе инвентаризации?

Спасибо, если мой вопрос не имеет смысла или нуждается в разъяснении, просто дайте мне знать.

Ответ 1

Чтобы использовать интерфейс Comparator, вы должны его реализовать и передать его как анонимный класс в Collections.sort(список List, Comparator c) в качестве второго параметра.

Если вы хотите передать только список Collections.sort(Список списка), то ваш класс Item должен реализовать Comparable.

Итак, в обоих случаях методы Collections.sort знают, как упорядочить элементы в вашем списке

вот пример кода:

Элемент класса, реализующий Comparable + Инвентарь, содержащий список элементов

public class Item implements Comparable<Item> {

    String id = null;

    public Item(String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return id;
    }

    @Override
    public int compareTo(Item o) {
        return - id.compareToIgnoreCase(o.id);
    }
}


public class Inventory {

    List<Item> items = new ArrayList<>();

    public void addItem(Item item) {
        items.add(item);
    }

    public static void main(String[] args) {
        Inventory inventory = new Inventory();
        inventory.addItem(new Item("2"));
        inventory.addItem(new Item("4"));
        inventory.addItem(new Item("1"));
        inventory.addItem(new Item("7"));

        Collections.sort(inventory.items, new Comparator<Item>() {
            @Override
            public int compare(Item o1, Item o2) {
                return o1.id.compareToIgnoreCase(o2.id);
            }
        });
        System.out.println(inventory.items);

        Collections.sort(inventory.items);
        System.out.println(inventory.items);

    }
}

Выход

[1, 2, 4, 7] // ascending
[7, 4, 2, 1] // descending since the compareTo method inverts the sign of the comparison result.

Ответ 2

EDIT: Прежде всего, несколько вещей:

  • Аннотация @Override не обязательна. Если Eclipse хочет, чтобы вы его надели, не волнуйтесь.
  • Не пишите свой собственный интерфейс компаратора. Удалите это определение NAO и используйте тот, который предоставляется Java. Повторное использование колеса, вероятно, нарушает Unspoken Code of Computer Programming примерно 15 различными способами. Используйте import java.util.Comparator; в самом верху вашего кода (до материала public class): a) используйте версию, данную Java, и b) совместите свой код с почти всем остальным, что существует в мире.

Интерфейс Comparator не используется для создания класса, который может привести себя в порядок. Это интерфейс Comparable.

Оба схожи, поэтому я опишу оба здесь.

java.util.Comparator

Интерфейс Comparator, как вы уже знаете, имеет один метод: compare. Компаратор является общим (использует угловые скобки <>) и берет тип, который он будет сравнивать внутри <>. Дело в том, что компараторы используются для сравнения предметов других классов. Например, я мог бы создать Компаратор для java.lang.Integers, который возвращает противоположность "естественного порядка" (как обычно упорядочиваются целые числа).

Компараторы используются в основном для того, чтобы другие объекты могли сортировать свои параметры, когда они не находятся в естественном порядке. Например, java.util.TreeSet класс использует Comparator для его сортировки.

java.lang.Comparable

Сопоставимая цель - сказать, что объект можно сравнить. Он также является общим и принимает тип, с которым его можно сравнить. Например, a Comparable<String> можно сравнить со строками.

Сопоставимый имеет один метод: compareTo(). В отличие от компаратора compare(), compareTo принимает один параметр. Он работает как compare, за исключением того, что он использует вызывающий объект как один параметр. Итак, comparableA.compareTo(comparableB) совпадает с comparator.compare(comparableA, comparableB).

Сопоставимый в основном устанавливает естественный порядок для объектов и является стандартным способом сравнения объектов. Роль компаратора заключается в том, чтобы переопределить этот естественный порядок, когда у вас разные потребности в сравнении или сортировке данных.

Сортировка ArrayList

Чтобы отсортировать List, вы можете использовать уже доступный метод: прокрутите вниз до sort в java.util.Collections class. Один метод использует компаратор, другой - нет. sort является статическим; используйте Collections.sort(...), а не Collections c = new Collections(); c.sort(...). (Collections даже не имеет конструктора, так что meh.)

Ответ 3

Вы смешиваете интерфейсы Comparator и Comparable.

Компаратор: http://docs.oracle.com/javase/6/docs/api/java/util/Comparator.html

Сопоставимо: http://docs.oracle.com/javase/6/docs/api/java/lang/Comparable.html

Целью компаратора является класс (объявленный анонимно на месте или иным образом), который может быть передан операции, которая требует упорядочения, и определяет сортировку, которая будет использоваться в элементе. Компаратор должен использоваться OUTSIDE класса, который нуждается в сортировке, если есть альтернативный способ, которым вы хотите отсортировать его.

Цель Comparable - сказать, что класс (который реализует Comparable) имеет естественный порядок - и это то, что он есть. Если ваш класс, который нуждается в сортировке, имеет естественный порядок, тогда определите его как Comparable. (класс, который реализует порядок сортировки Sortable, по-прежнему может быть переопределен компаратором. С другой стороны, если класс не является Сопоставимый, а также передача Компаратора является обязательной для того, чтобы заказ был возможен.)

Ответ 4

Вы внедрили неправильный интерфейс, вы хотите Comparable

Ответ 5

Использование аннотации @Override - стандартная практика в редакторах, таких как eclipse, netbeans, чтобы уведомить разработчика о том, что он переопределяет/реализует метод родительского класса/интерфейса. Это необязательно.

Не используйте этот интерфейс в своем классе Item. Создайте новый класс и реализуйте интерфейс Comparator.

public class ItemCompare implements Comparator<Item> {

    @Override
    public int compare(Item a, Item b) {
        if (a.getID().compareToIgnoreCase(b.getID())>0)
            return 1;
        else if (a.getID().compareToIgnoreCase(b.getID())<0)
            return -1;
        return 0;
    }
} 

И затем, в своем основном классе, сделайте следующее:

ArrayList al = new ArrayList<Item>

Collections.sort(al, new ItemCompare())