Как я могу переопределить метод compareto, чтобы заказать зарплату сотрудников?

У меня есть 2 класса: человек и сотрудник и интерфейс Human. В моем классе Person у меня есть метод compareTo (Human h), который присваивает +1, -1 и 0 возрасту человека. Сотрудник моего класса = общедоступный класс Сотрудник расширяет Person, реализует Human = У меня также есть метод compareTo, который должен учитывать зарплату сотрудников, если возраст одинаковый (для сортировки).

Я не совсем уверен, как справиться с этим? Мне удалось создать compreTo для класса Persons, но я не уверен, как здесь отсортировать как человека, так и сотрудника.

Спасибо вам за помощь.

Я уже пробовал это в своем классе Employee:

compareTo (Human h) {
Employee e = (Employee)h;

if (super.compareTo(h) == 0 && getSalary ()< e.getSalary())
    return -1;
    else if (super.compareTo(h) == 0 && getSalary () == e.getSalary())
        return 0;
    else 
        return 1;

}

Это работает, но я хочу иметь возможность использовать instanceof для решения этой проблемы:

     public int compareTo(Human h) {

    // TODO Auto-generated method stub

     if (getAge() < h.getAge()) {
          return -1;
        } else if (getAge() > h.getAge()) {
          return 1;
        } else {
            Employee e = (Employee)h;
          // age is identical: compare salary
          if (getSalary() < e.getSalary()) {
            return -1;
          } else if (getSalary() > e.getSalary()) {
            return 1;
          } else {
            return 0;
          }
        }
      }

Ниже я доказал объем кода, который, по моему мнению, необходим для этого вопроса:

public interface Human extends Comparable <Human>{
//extends = is a


int getAge();
String getName();

}



public class Person implements Human {
    private int age; 
private String name;
    public int compareTo(Human h) {


    //System.out.println(this.age + ". " +h.getAge());
    if (h.getAge() > getAge())
        return -1;
    else if (getAge() == h.getAge())
        return 0;
    else 
        return 1;    
}

public class Employee extends Person implements Human{


private int salary;
private String employer; 

public int compareTo(Human h) {
 ???
}



  public static void main(String[] args) {
  ArrayList<Human> p = new ArrayList<Human>();
    p.add(new Person("A", 1));
    p.add(new Employee("B", 31, "E1", 45000));
    p.add(new Person("C", 122));
    p.add(new Employee("D", 3, "E2", 54321));
    p.add(new Person("E", 21));
    p.add(new Employee("F", 31, "E1", 21000));
    p.add(new Employee("G", 31, "E1", 38000));
    System.out.println(p);
    Collections.sort(p);
    System.out.println(p); }

Это то, что я пытаюсь проверить:

non sorted: [Person:[A, 1], Employee:[B, 31][E1, 45000], Person:[C, 122], Employee:[D, 3][E2, 54321], Person:[E, 21], Employee:[F, 31][E1, 21000], Employee:[G, 31][E1, 38000]]

sorted: [Person:[A, 1], Employee:[D, 3][E2, 54321], Person:[E, 21], Employee:[F, 31][E1, 21000], Employee:[G, 31][E1, 38000], Employee:[B, 31][E1, 45000], Person:[C, 122]]

Любая помощь будет оценена по достоинству.


person Anika    schedule 27.10.2019    source источник


Ответы (2)


Для обеспечения правильного заказа; метод compareTo должен соответствовать договору определяется интерфейсом Comparable.

К сожалению, нет возможности расширить Person; переопределение compareTo в Employee для сравнения зарплаты при сохранении контракта.

Простое решение — передать компаратор в Collections.sort(); гарантируя, что все элементы коллекции используют одну и ту же реализацию компаратора:

Comparator.comparingInt(Human::getAge).thenComparingInt(h -> h instanceof Employee ? ((Employee) h).getSalary() : 0)
person Robin Rozo    schedule 27.10.2019

Вы можете добиться этого, просто реализовав метод compareTo в Person и Employee следующим образом:

// In Person class
@Override
public int compareTo(Human h) {
    return age - h.getAge();
}

И

// In Employee class:
@Override
public int compareTo(Human h) {
    int result = super.compareTo(h);
    if ((result == 0) && (h instanceof Employee)) {
        result = salary - ((Employee) h).salary;
    }
    return result;
}

Ваше здоровье!

person Abs    schedule 27.10.2019
comment
Мне было интересно, как насчет того, чтобы добавить еще одно сравнение классов к этому методу? пример: у меня есть класс менеджера, который расширяется от сотрудника, но у меня есть дополнительный объект команды в классе менеджера, поэтому, если бы зарплаты были одинаковыми, я бы посмотрел на размер команды. - person Anika; 27.10.2019
comment
Если вы не хотите полагаться на compareTo (или если вы хотите обрабатывать другие несопоставимые объекты), вы можете определить компаратор (в менеджере или где-либо еще) и использовать его для сортировки (вы можете связать несколько функций, изменить порядок и т. .. : см.: docs.oracle.com/javase /8/docs/api/java/util/Comparator.html) - person Abs; 28.10.2019