2

I have 2 classes: person and employee and an interface Human Within my Person class, I have a compareTo Method (Human h) Which assigns the +1,-1 and 0 for the person's age. My class employee = public class Employee extends Person implements Human = I have a compareTo method as well, which needs to account for the employees salary if the age is the same (for sorting).

I am not quite sure how to tackle this? I was able to make the compreTo for the Persons class but I am not sure how to have both person and employe sorted here.

Thank you for the help.

I have already tried this in my Employee class:

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;

}

This one works, but I want to be able to use instanceof to solve this problem:

     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;
          }
        }
      }

Below I had proved the amount of code I think is necessary for this question:

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); }

This is what I am trying to test:

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]]

Any help would be appreciated.

Anika
  • 103
  • 1
  • 8

2 Answers2

0

To ensure a correct ordering; the compareTo method needs to satisfy the contract specified by the Comparable interface.

Unfortunately, there is no way to extend Person; overriding compareTo in Employee to compare the salary while preserving the contract.

A simple solution is to pass a comparator to Collections.sort(); ensuring that all the elements of the collection use the same comparator implementation:

Comparator.comparingInt(Human::getAge).thenComparingInt(h -> h instanceof Employee ? ((Employee) h).getSalary() : 0)
Robin Rozo
  • 154
  • 5
0

You can achieve this by simply implementing the compareTo method in Person and Employee as follow:

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

And

// 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;
}

Cheers!

Abs
  • 300
  • 1
  • 10
  • I was wondering how about would I add another class comparison to this method? ex: I have a manager class which extends from employee but I have a team object extra in manager class, so if the salaries were the same then I would look at the team size. – Anika Oct 27 '19 at 18:41
  • If you don't want to rely on the compareTo (or if you want to handle other non comparable objects) you can define a comparator (in manager or elsewhere) and use that for sorting (your can chain several functions, change order,... : see: https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html) – Abs Oct 28 '19 at 10:24