Java 排序逻辑和识别两个对象的最大值
Java Sorting logic and Identifying max of two objects
要求是找到部门 2 组号 8 和部门 2 组号 4 的最新员工对象(最新日期)。同理,部门 1 组号 8 和部门 1 组号 4。我只需要最终列表中以上所有对象中的最新一个对象。
写的比较逻辑是按照需要的顺序排序,只保留需要的对象。但是我被困住了,因为我找不到从排序列表中保留单个对象的方法。无论如何我可以实现它吗?忽略比较器逻辑,如果您可以建议使用流或其他良好实现的任何 ootb 方式,我将不胜感激?
SimpleDateFormat df = new SimpleDateFormat("dd-mm-yyyy");
List<Employee> employees = new LinkedList<Employee>(Arrays.asList(
new Employee("Emp1", df.parse("12-08-2020"),
new EmpType("1", new Group(8))),
new Employee("Emp2", df.parse("11-08-2020"),
new EmpType("2", new Group(8))),
new Employee("Emp3", df.parse("10-08-2020"),
new EmpType("2", new Group(4))),
new Employee("Emp4", df.parse("17-08-2020"),
new EmpType("2", new Group(8))),
new Employee("Emp5", df.parse("19-08-2020"),
new EmpType("1", new Group(4)))));
/* Sorting logic to sort by group number first then by department and then by date */
Collections.sort(employees, new Comparator<Employee>() {
@Override
public int compare(Employee employee, Employee t1) {
int val = 0;
if (employee.getEmpType().getGroup().getNumber() < t1.getEmpType().getGroup().getNumber()) {
val = 1;
} else if (employee.getEmpType().getGroup().getNumber() > t1.getEmpType().getGroup()
.getNumber()) {
val = -1;
} else {
val = 0;
}
if (val == 0) {
val = -(employee.getEmpType().getDepartment().compareTo(t1.getEmpType().getDepartment()));
}
if (val == 0) {
val = -employee.getDate().compareTo(t1.getDate());
}
return val;
}
});
您可以将 Collections.max
与您已实现的 Comparator
一起使用,而不是排序。
编辑以解决评论中的讨论:
如果我正确理解数据结构,EmpType
封装了我们想要为其找到“最新”员工的唯一组合。假设它正确实现了 equals(Object)
和 hashCode()
方法,您可以流式传输列表并将其收集到从 EmpType
到最新员工的映射:
Map<EmpType, Employee> latestEmployees =
employees.stream()
.collect(Collectors.toMap(
Employee::getEmpType,
Function.identity(),
BinaryOperator.maxBy(
Comparator.comparing(Employee::getDate))));
我觉得把业务逻辑混在排序函数里面很乱。
为什么不根据员工的日期对员工进行降序排序并解析结果数组,直到第一次满足您的条件?
您可以使用 Stream API 的 Collectors.toMap
按 EmpType
进行映射,并使用 BinaryOperator.maxBy
获取具有相同 EmpType
的每个组的最新日期作为价值观。然后获取newArrayList
中map的值。这里按 EmpType
映射,因为它包含组号和部门,您需要 EmpType
.
的适当等号和哈希码实现
List<Employee> res = new ArrayList(employees.stream()
.collect(Collectors.toMap(Employee::getEmpType, Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(Employee::getDate)))).values());
或者您可以创建一对组号和部门,如 new AbstractMap.SimpleEntry(e.getEmpType().getDepartment(), e.getEmpType().getGroup().getNumber())
作为键而不是 EmpType
然后不需要 equals 和 hashcode 实现
List<Employee> res = new ArrayList(employees.stream()
.collect(Collectors.toMap(
e -> new AbstractMap.SimpleEntry(e.getEmpType().getDepartment(),
e.getEmpType().getGroup().getNumber()),
Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(Employee::getDate))))
.values());
要求是找到部门 2 组号 8 和部门 2 组号 4 的最新员工对象(最新日期)。同理,部门 1 组号 8 和部门 1 组号 4。我只需要最终列表中以上所有对象中的最新一个对象。
写的比较逻辑是按照需要的顺序排序,只保留需要的对象。但是我被困住了,因为我找不到从排序列表中保留单个对象的方法。无论如何我可以实现它吗?忽略比较器逻辑,如果您可以建议使用流或其他良好实现的任何 ootb 方式,我将不胜感激?
SimpleDateFormat df = new SimpleDateFormat("dd-mm-yyyy");
List<Employee> employees = new LinkedList<Employee>(Arrays.asList(
new Employee("Emp1", df.parse("12-08-2020"),
new EmpType("1", new Group(8))),
new Employee("Emp2", df.parse("11-08-2020"),
new EmpType("2", new Group(8))),
new Employee("Emp3", df.parse("10-08-2020"),
new EmpType("2", new Group(4))),
new Employee("Emp4", df.parse("17-08-2020"),
new EmpType("2", new Group(8))),
new Employee("Emp5", df.parse("19-08-2020"),
new EmpType("1", new Group(4)))));
/* Sorting logic to sort by group number first then by department and then by date */
Collections.sort(employees, new Comparator<Employee>() {
@Override
public int compare(Employee employee, Employee t1) {
int val = 0;
if (employee.getEmpType().getGroup().getNumber() < t1.getEmpType().getGroup().getNumber()) {
val = 1;
} else if (employee.getEmpType().getGroup().getNumber() > t1.getEmpType().getGroup()
.getNumber()) {
val = -1;
} else {
val = 0;
}
if (val == 0) {
val = -(employee.getEmpType().getDepartment().compareTo(t1.getEmpType().getDepartment()));
}
if (val == 0) {
val = -employee.getDate().compareTo(t1.getDate());
}
return val;
}
});
您可以将 Collections.max
与您已实现的 Comparator
一起使用,而不是排序。
编辑以解决评论中的讨论:
如果我正确理解数据结构,EmpType
封装了我们想要为其找到“最新”员工的唯一组合。假设它正确实现了 equals(Object)
和 hashCode()
方法,您可以流式传输列表并将其收集到从 EmpType
到最新员工的映射:
Map<EmpType, Employee> latestEmployees =
employees.stream()
.collect(Collectors.toMap(
Employee::getEmpType,
Function.identity(),
BinaryOperator.maxBy(
Comparator.comparing(Employee::getDate))));
我觉得把业务逻辑混在排序函数里面很乱。
为什么不根据员工的日期对员工进行降序排序并解析结果数组,直到第一次满足您的条件?
您可以使用 Stream API 的 Collectors.toMap
按 EmpType
进行映射,并使用 BinaryOperator.maxBy
获取具有相同 EmpType
的每个组的最新日期作为价值观。然后获取newArrayList
中map的值。这里按 EmpType
映射,因为它包含组号和部门,您需要 EmpType
.
List<Employee> res = new ArrayList(employees.stream()
.collect(Collectors.toMap(Employee::getEmpType, Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(Employee::getDate)))).values());
或者您可以创建一对组号和部门,如 new AbstractMap.SimpleEntry(e.getEmpType().getDepartment(), e.getEmpType().getGroup().getNumber())
作为键而不是 EmpType
然后不需要 equals 和 hashcode 实现
List<Employee> res = new ArrayList(employees.stream()
.collect(Collectors.toMap(
e -> new AbstractMap.SimpleEntry(e.getEmpType().getDepartment(),
e.getEmpType().getGroup().getNumber()),
Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(Employee::getDate))))
.values());