【问题标题】:compareTo method logic to sort List by multiple variablescompareTo 方法逻辑按多个变量对 List 进行排序
【发布时间】:2019-05-08 03:33:37
【问题描述】:

问题:创建一个独立的 jar 可执行文件,它将按姓名、年龄和经验升序打印出现在面试中的候选人列表。

我无法弄清楚 compareTo 方法逻辑以便能够对给定问题中的 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;
  }
}

员工控制器

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

}

【问题讨论】:

  • 为什么你认为逻辑是错误的?您可能想要显示一组输入,以及您期望的结果顺序,以及您的代码会产生什么结果。您的 getEmployees() 方法中的数据似乎只是按名称排序,因为没有一个名称相同。
  • 当我为“age”和“exp”编写代码时,我的 IDE 给了我一个错误,我得到的错误是“无法解析方法 compareTo(int)”。预期的输出是按姓名、年龄和经验升序排列的面试候选人列表
  • 你用的是什么版本的java?从 Java 7 开始,Integer 有一个 compareTo 方法,并且在此之前将 int 自动装箱为 Integer。也许尝试age.compareTo(emp.age) 没有不必要的(this.age)
  • 项目版本为java版本11.0.2。我将其更改为“result = age.compareTo(emp.age);”我仍然遇到同样的错误“无法解析 compareTo(int)
  • 是的,我可以看到...好的,下面有新答案

标签: java list sorting comparable


【解决方案1】:
public class Employee implements Comparable<Employee> {

    private String name;
    private int age;
    private int exp;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public int getExp() {
        return exp;
    }
    public void setExp(int exp) {
        this.exp = exp;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Employee(String name, int age, int exp) {
        super();
        this.name = name;
        this.age = age;
        this.exp = exp;
    }
    public Employee() {
  }

    @Override
    public int compareTo(Employee emp) {
    //replace your comparator here
       return (this.getAge() - emp.getAge());
  }

}
-------------------------------------------------------
@Service
public class EmployeeService {


    public List<Employee> getEmployees() {
        List<Employee> emp = new ArrayList<>();
        Employee emp1 = new Employee("Sandhya",20,0);
        Employee emp2 = new Employee("Kemp",24,2);
        Employee emp3 = new Employee("Anil",22,3);
        Employee emp4 = new Employee("Kumar",30,6);
        Employee emp5 = new Employee("Tim",32,7);
        emp.add(emp1);
        emp.add(emp2);
        emp.add(emp3);
        emp.add(emp4);
        emp.add(emp5);

        return emp;
    }




}
---------------------------------------------------------------------------

@RestController
public class EmployeeController {

  @Autowired
  EmployeeService employeeService;

  @RequestMapping("/")
    public List<Employee> getEmpList(){
    List<Employee> empController = employeeService.getEmployees();
    Collections.sort(empController);
        return empController;
    }

}

【讨论】:

    【解决方案2】:

    无需实现Comparable并重写compareTo方法,使用Comparator即可

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

    并且使用Collections.sort() 使用传递的Comparator 对列表进行排序

    Collections.sort(eList,c);
    

    通过使用 Comparable

    问题是ageexpint 类型,这是原始类型,如果您不能使用compareTo 方法,请将它们的类型更改为Integer 包装对象或使用Integer.compare(int a, int b) 方法

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

    这样您就可以在ageexp 上使用compareTo

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

    【讨论】:

    • 为什么要调用 Integer.compare 或 String.compareTo 两次?
    • 我不同意将int age 更改为Integer age 的建议,因为某些代码无法编译。这是一个非常糟糕的理由。
    【解决方案3】:

    因此,问题似乎是您的 compareTo 中没有发生自动装箱,因此您可以将它们装箱,或者仅将 age/exp 作为原始整数处理。 所以这样做,将原始 int 转换为 Integer 具有 compareTo:

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

    【讨论】:

      【解决方案4】:

      您的代码看起来非常好,我不得不思考一下为什么它可能是错误的。

      关键是intString 在Java 中的类型非常不同。 int 是所谓的原始类型(因为它不是由其他类型组成的),String 是对象类型。按照惯例,原始类型的名称以小写字母开头,而对象类型的名称以大写字母开头。

      只有对象类型可以有方法。

      由于this.age 的类型是int,因此是原始类型,因此不允许使用(this.age).compareTo(...)。相反,你必须写Integer.compare(this.age, emp.age)

      编译器的错误信息并没有真正的帮助。与其说“方法 int.compareTo 未找到”,不如说“this.age 的类型是 int,因为它是原始类型,所以不能对其调用任何方法”。

      【讨论】:

        【解决方案5】:

        对你的排序问题代码的正确修改是

        //In service class
        
        public List<Employee> getEmployees() {
        
                Employee e1 = new Employee("Sandhya", 24, 0);
                Employee e2 = new Employee("Kemp", 22, 2);
                Employee e3 = new Employee("Anil", 26, 3);
                Employee e4 = new Employee("Kumar", 30, 6);
                Employee e5 = new Employee("Tim", 32, 7);
        
                List<Employee> elist = Arrays.asList(e1,e2,e3,e4,e5);
        
                return elist;
        
        //in controller class
        
        @Autowired
            EmployeeService empserv;
            
            @RequestMapping(value="/")
            public List<Employee> getEmpList(){
                List<Employee> list = empserv.getEmployees();
                Collections.sort(list);
                return list;
            }
        
        
        //in Employee class, since it was asked to sort according to age of the employees
        
        @Override
        
            public int compareTo(Employee o) {
                int result = Integer.compare(this.getAge(), o.getAge());;
                /*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;
            }
        

        【讨论】:

          【解决方案6】:

          通过这个测试。

          在Employee类中添加

          public int compareTo(Employee emp) { 返回 this.getAge() - emp.getAge();

          }

          在 EmployeeService 中,只需在 getEmployess 方法中从 TestEmployee 类中复制列表数据并返回列表。

          在EmployeeController 中添加@RequestMapping("/") 并使用Collections.sort(list) 并返回列表;

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-07-28
            • 1970-01-01
            • 2012-11-25
            • 2011-06-20
            • 1970-01-01
            • 1970-01-01
            • 2019-04-26
            相关资源
            最近更新 更多