按多个变量对 List 进行排序的 compareTo 方法逻辑
compareTo method logic to sort List by multiple variables
问题:创建一个独立的 jar 可执行文件,它将打印出现在面试中的候选人列表,按姓名、年龄和经验升序排列。
我在弄清楚 compareTo 方法逻辑以便能够对给定问题中的 3 个字段进行排序时遇到问题。
员工Class
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;
}
}
员工服务Class
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;
}
}
无需实现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
以便您可以在 age
和 exp
上使用 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;
}
你的代码看起来非常好,我不得不思考一下为什么它可能是错误的。
重点是 int
和 String
类型在 Java 中有很大不同。 int
是一个so-called原始类型(因为它不是由其他类型组成的),String
是一个对象类型。按照惯例,基本类型的名称以小写字母开头,而对象类型的名称以大写字母开头。
只有对象类型可以有方法。
由于 this.age
的类型是 int
并且因此是原始类型,所以 (this.age).compareTo(...)
是不允许的。相反,你必须写 Integer.compare(this.age, emp.age)
.
编译器的错误信息并没有太大帮助。与其说 "method int.compareTo not found",不如说 "the type of this.age is int, and since that is a primitive type, no methods can be called on it".
所以,问题似乎是您的 compareTo 中没有发生自动装箱,因此您可以将它们装箱,或者只将 age/exp 作为原始整数处理。
所以这样做,将原始 int
转换为具有 compareTo:
的 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;
}
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;
}
}
你排序问题的代码正确修改为
//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;
}
要通过这个测试。
在员工 class 中只需添加
public int compareTo(员工 emp) {
return this.getAge() - emp.getAge();
}
在 EmployeeService 中只需从 TestEmployee class 中的 getEmployess 方法和 return 列表中复制列表数据。
在 EmployeeController 中添加 @RequestMapping("/") 并使用 Collections.sort(list) 和 return list;
问题:创建一个独立的 jar 可执行文件,它将打印出现在面试中的候选人列表,按姓名、年龄和经验升序排列。
我在弄清楚 compareTo 方法逻辑以便能够对给定问题中的 3 个字段进行排序时遇到问题。
员工Class
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;
}
}
员工服务Class
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;
}
}
无需实现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
以便您可以在 age
和 exp
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;
}
你的代码看起来非常好,我不得不思考一下为什么它可能是错误的。
重点是 int
和 String
类型在 Java 中有很大不同。 int
是一个so-called原始类型(因为它不是由其他类型组成的),String
是一个对象类型。按照惯例,基本类型的名称以小写字母开头,而对象类型的名称以大写字母开头。
只有对象类型可以有方法。
由于 this.age
的类型是 int
并且因此是原始类型,所以 (this.age).compareTo(...)
是不允许的。相反,你必须写 Integer.compare(this.age, emp.age)
.
编译器的错误信息并没有太大帮助。与其说 "method int.compareTo not found",不如说 "the type of this.age is int, and since that is a primitive type, no methods can be called on it".
所以,问题似乎是您的 compareTo 中没有发生自动装箱,因此您可以将它们装箱,或者只将 age/exp 作为原始整数处理。
所以这样做,将原始 int
转换为具有 compareTo:
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;
}
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;
}
}
你排序问题的代码正确修改为
//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;
}
要通过这个测试。
在员工 class 中只需添加
public int compareTo(员工 emp) { return this.getAge() - emp.getAge();
}
在 EmployeeService 中只需从 TestEmployee class 中的 getEmployess 方法和 return 列表中复制列表数据。
在 EmployeeController 中添加 @RequestMapping("/") 并使用 Collections.sort(list) 和 return list;