Java-компаратор, как сортировать по целому числу? - программирование
Подтвердить что ты не робот

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() + ", ");
}
}
4b9b3361

Ответ 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. Я думал, что это может быть полезно другим в том же месте, чтобы посмотреть, что я в итоге решил.