Java-компаратор, как сортировать по целому числу?
Я пытаюсь изучить компаратор в java, и я нашел этот отличный пример онлайн, мой вопрос заключается в том, как изменить этот код так, чтобы имена домашних животных упорядочивались по возрасту и в порядке убывания, так что старший является первым и самым молодым является последний?
class Dog implements Comparator<Dog>, Comparable<Dog>{
private String name;
private int age;
Dog(){
}
Dog(String n, int a){
name = n;
age = a;
}
public String getDogName(){
return name;
}
public int getDogAge(){
return age;
}
// Overriding the compareTo method
public int compareTo(Dog d){
return (this.name).compareTo(d.name);
}
// Overriding the compare method to sort the age
public int compare(Dog d, Dog d1){
return d.age - d1.age;
}
}
public class Example{
public static void main(String args[]){
// Takes a list o Dog objects
List<Dog> list = new ArrayList<Dog>();
list.add(new Dog("Shaggy",3));
list.add(new Dog("Lacy",2));
list.add(new Dog("Roger",10));
list.add(new Dog("Tommy",4));
list.add(new Dog("Tammy",1));
Collections.sort(list);// Sorts the array list
for(Dog a: list)//printing the sorted list of names
System.out.print(a.getDogName() + ", ");
// Sorts the array list using comparator
Collections.sort(list, new Dog());
System.out.println(" ");
for(Dog a: list)//printing the sorted list of ages
System.out.print(a.getDogName() +" : "+
a.getDogAge() + ", ");
}
}
Ответы
Ответ 1
Простое изменение
public int compare(Dog d, Dog d1) {
return d.age - d1.age;
}
к
public int compare(Dog d, Dog d1) {
return d1.age - d.age;
}
должен сортировать их в обратном порядке возраста, если это то, что вы ищете.
Update:
@Arian прав в своих комментариях, один из принятых способов объявления компаратора для собаки будет там, где вы объявляете его публичным статическим конечным полем в самом классе.
class Dog implements Comparable<Dog> {
private String name;
private int age;
public static final Comparator<Dog> DESCENDING_COMPARATOR = new Comparator<Dog>() {
// Overriding the compare method to sort the age
public int compare(Dog d, Dog d1) {
return d.age - d1.age;
}
};
Dog(String n, int a) {
name = n;
age = a;
}
public String getDogName() {
return name;
}
public int getDogAge() {
return age;
}
// Overriding the compareTo method
public int compareTo(Dog d) {
return (this.name).compareTo(d.name);
}
}
Затем вы можете использовать его где-нибудь в своем коде, где вы хотели бы сравнить собак следующим образом:
// Sorts the array list using comparator
Collections.sort(list, Dog.DESCENDING_COMPARATOR);
Еще одна важная вещь, которую следует помнить при реализации Comparable, заключается в том, что важно, чтобы compareTo выполнял последовательно с равными. Хотя это и не требуется, неспособность сделать это может привести к странному поведению в некоторых коллекциях, таких как некоторые реализации наборов. См. этот пост для получения дополнительной информации о разумных принципах реализации compareTo.
Ответ 2
Просто замените:
return d.age - d1.age;
По:
return ((Integer)d.age).compareTo(d1.age);
Или инвертируйте вспять список:
return ((Integer)d1.age).compareTo(d.age);
EDIT:
Исправлена проблема с памятью.
Действительно, лучшим решением является изменение поля age
в классе Dog
на Integer
, потому что есть много преимуществ, таких как возможность null
...
Ответ 3
public class DogAgeComparator implements Comparator<Dog> {
public int compare(Dog o1, Dog o2) {
return Integer.compare(o1.getAge(), o2.getId());
}
}
Ответ 4
Один простой способ -
Comparator<Dog> ageAscendingComp = ...;
Comparator<Dog> ageDescendingComp = Collections.reverseOrder(ageAscendingComp);
// then call the sort method
В боковом примечании собака действительно не должна реализовывать Comparator
. Это означает, что вам нужно делать такие странные вещи, как
Collections.sort(myList, new Dog("Rex", 4));
// ^-- why is a new dog being made? What are we even sorting by?!
Collections.sort(myList, myList.get(0));
// ^-- or perhaps more confusingly
Скорее вы должны сделать Compartors как отдельные классы.
например.
public class DogAgeComparator implments Comparator<Dog> {
public int compareTo(Dog d1, Dog d2) {
return d1.getAge() - d2.getAge();
}
}
Это имеет дополнительное преимущество, что вы можете использовать имя класса, чтобы сказать, как сортировщик сортирует список. например.
Collections.sort(someDogs, new DogNameComparator());
// now in name ascending order
Collections.sort(someDogs, Collections.reverseOrder(new DogAgeComparator()));
// now in age descending order
Вы также не должны иметь инструмент Dog Comparable
. Интерфейс Comparable
используется для обозначения того, что существует некоторый естественный и естественный способ упорядочения этих объектов (например, для чисел и строк). Теперь это не относится к объектам Dog, поскольку иногда вы можете сортировать по возрасту, а иногда вы можете сортировать по имени.
Ответ 5
С помощью Java 8 вы можете использовать:
Comparator.comparingInt(Dog::getDogAge).reversed();
Ответ 6
Если у вас есть доступ к API Java 8 Comparable, Comparable.comparingToInt()
может быть полезным. (См. Java 8 Сопоставимая документация).
Например, Comparator<Dog>
для сортировки экземпляров Dog
, по убыванию по возрасту, может быть создано со следующим:
Comparable.comparingToInt(Dog::getDogAge).reversed();
Функция принимает лямбда-отображение T
- Integer
и создает восходящий компаратор. Привязанная функция .reversed()
превращает восходящий компаратор в нисходящий компаратор.
Примечание: хотя это может быть неприменимо для большинства версий Android, я столкнулся с этим вопросом, ища аналогичную информацию для приложения, отличного от Android Java. Я думал, что это может быть полезно другим в том же месте, чтобы посмотреть, что я в итоге решил.