Логика метода сравнения для сортировки списка по нескольким переменным - PullRequest
2 голосов
/ 08 мая 2019

Проблема: создайте автономный исполняемый файл jar, в котором будет напечатан список кандидатов, отображаемых в порядке сортировки интервью по возрастанию и названию.

У меня проблемы с выяснением логики метода сравнения, чтобы иметь возможностьчтобы отсортировать 3 поля в данной задаче.

Класс сотрудника

package com.example.demo.employee;

public class Employee implements Comparable<Employee> {

private String name;
private int age;
private int exp;

public Employee(String name, int age, int exp) {
    super();
    this.name = name;
    this.age = age;
    this.exp = exp;
}

public Employee() {
}

// getter setter

@Override
public int compareTo(Employee emp) {

    // I do not think this logic is correct
    // I have read the other stack overflow posts with similar problem
    // but failing to under stand what to do in this method.

    int result = (this.name).compareTo(emp.name);
    if ( result == 0 ) {
        result = (this.age).compareTo(emp.age);
    }

    if ( result == 0 ) {
        result = (this.exp).compareTo(emp.exp);
    }
    return result;
 }

}

Класс обслуживания сотрудника

package com.example.demo.employee;

import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class EmployeeService {


public List<Employee> getEmployees() {

    Employee e1 = new Employee("Sandhya", 20, 0);
    Employee e2 = new Employee("Kemp", 24, 2);
    Employee e3 = new Employee("Anil", 22, 3);
    Employee e4 = new Employee("Kumar", 30, 6);
    Employee e5 = new Employee("Tim", 32, 7);

public List<Employee> getEmployees() {

    List<Employee> eList = new ArrayList<>();
    eList.add(e1);
    eList.add(e2);
    eList.add(e3);
    eList.add(e4);
    eList.add(e5);

    Collections.sort(eList);

    return eList;
  }
}

EmployeeController

package com.example.demo.employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class EmployeeController {

@Autowired
EmployeeService es;

@RequestMapping(value = "/")
public List<Employee> getEmpList(){
    List<Employee> list = es.getEmployees();
    return list;
  }

}

Ответы [ 3 ]

2 голосов
/ 08 мая 2019

Нет необходимости реализовывать Comparable и переопределять метод compareTo, просто используйте Comparator

Comparator<Employee> c = Comparator.comparing(Employee::getName)
                                       .thenComparing(Employee::getAge)
                                       .thenComparing(Employee::getExp);

И использование Collections.sort() для сортировки списка с использованием переданного Comparator

Collections.sort(eList,c);

При использовании Comparable

Проблема в том, что age и exp имеют тип int, который является примитивным, если вы не можете использовать метод compareTo, измените их тип на Integer объект-оболочку или используйте Integer.compare(int a, int b) метод

private int age;    // to private Integer age
private int exp;    // to private Integer exp

Так что вы можете использовать compareTo на age и exp

this.getAge().compareTo(o.getAge());
this.getExp().compareTo(o.getExp());

Если не смотреть на мое решение ниже, используя Integer.compare(int a, int b)

решение

@Override
public int compareTo(Employee o) {
    int result = this.getName().compareTo(o.getName());
    if (result == 0) {
        result = Integer.compare(this.getAge(), o.getAge());
        if (result == 0) {
            return Integer.compare(this.getExp(), o.getExp());
        }
        return result;
    }
    return result;
}
1 голос
/ 08 мая 2019

Итак, проблема, похоже, в том, что автобокс не происходит в вашем CompareTo, поэтому вы можете либо пометить их, либо просто работать с age / exp как примитивные целые числа. Сделайте это, преобразовав примитив int в Integer, который сравнивает:

public int compareTo(Employee emp) {
    int result = (this.name).compareTo(emp.name);
    if ( result == 0 ) {
        result = Integer.valueOf(age).compareTo(emp.age);
    }
    if ( result == 0 ) {
        result = Integer.valueOf(exp).compareTo(emp.exp);
    }
    return result;
 }

поочередно, вы можете сделать это, оставив примитивы в покое:

public int compareTo(Employee emp) {
    int result = (this.name).compareTo(emp.name);
    if ( result == 0 ) {
        result = Integer.compare( age, emp.age );
    }
    if ( result == 0 ) {
        result = Integer.compare( exp, emp.exp );
    }
    return result;
 }
1 голос
/ 08 мая 2019

Ваш код выглядит действительно хорошо, и мне пришлось немного подумать, почему он вообще может быть неправильным.

Дело в том, что типы int и String сильно отличаются в Java.int - это так называемый примитивный тип (потому что он не состоит из других типов), а String - это тип объекта.По соглашению имена типов примитивов начинаются со строчной буквы, а имена типов объектов начинаются с заглавной буквы.

Методы могут быть только у типов объектов.

Поскольку тип this.age is int и, следовательно, примитивный тип, (this.age).compareTo(...) не допускается.Вместо этого вы должны написать Integer.compare(this.age, emp.age).

Сообщение об ошибке компилятора не очень полезно.Вместо того чтобы говорить «метод int.compareTo not found», он должен скорее сказать «тип this.age - int, и, поскольку он является примитивным типом, к нему нельзя вызывать методы».

...