Как использовать интерфейс 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())