英文:
Java Sorting logic and Identifying max of two objects
问题
要求是找到具有部门2中组号为8且在部门2中具有组号为4的最新员工对象(最新日期)。同样地,要在部门1中找到组号为8且在部门1中具有组号为4的情况。我只需要在最终列表中保留上述所有情况中的一个最新对象。
编写的比较逻辑是按照所需的顺序进行排序,并仅保留所需的对象。但是我陷入了困境,因为我无法找到一种从排序列表中保留单个对象的方法。是否有任何方法可以实现这一点?请忽略比较器逻辑,如果您可以建议使用流或其他良好的实现方式,我将不胜感激。
SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy");
List<Employee> employees = new LinkedList<>(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;
}
});
英文:
The requirement is to find the latest employee objects (latest date) having group number 8 with department 2 and having group number 4 within department 2. Same way group number 8 within department 1 and group number 4 in department 1. I only need the latest one object of all the above in the final list.
The comparison logic written was to sort it on the required order and retain only the required object. But I am stuck as I cannot find a way to retain single object from the sorted list. Is there anyway i can achieve it? Ignore the Comparator logic, appreciate if you can suggest any ootb way using stream or other good implementation?
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;
}
});
答案1
得分: 2
代替排序,您可以使用与您实现的相同“Comparator”的Collections.max
。
编辑以回应评论中的讨论:
如果我正确理解数据结构,EmpType
封装了我们想要找到“最新”雇员的唯一组合。假设它对 equals(Object)
和 hashCode()
方法有适当的实现,您可以对列表进行流式处理,并将其收集到从 EmpType
到最新雇员的映射中:
Map<EmpType, Employee> latestEmployees =
employees.stream()
.collect(Collectors.toMap(
Employee::getEmpType,
Function.identity(),
BinaryOperator.maxBy(
Comparator.comparing(Employee::getDate))));
英文:
Instead of sorting, you could use Collections.max
with the same Comparator
you've implemented.
EDIT to address the discussion in the comments:<br/>
If I understand the data structure correctly, EmpType
encapsulates the unique combination we want to find the "latest" employee for. Assuming it has a proper implementation of the equals(Object)
and hashCode()
methods, you could stream the list and collect it to a map from the EmpType
to the latest employee:
Map<EmpType, Employee> latestEmployees =
employees.stream()
.collect(Collectors.toMap(
Employee::getEmpType,
Function.identity(),
BinaryOperator.maxBy(
Comparator.comparing(Employee::getDate))));
</details>
# 答案2
**得分**: 1
我觉得在排序函数内部混合业务逻辑相当混乱。
为什么不只是根据员工的日期降序排列,然后在结果数组中遍历,直到第一次满足您的条件为止?
<details>
<summary>英文:</summary>
I find it quite messy to mix the business logic inside the sort function.
Why not just sort the Employees descendingly accoring to their date and parse through the resulting array untill your conditions are met for the first time?
</details>
# 答案3
**得分**: 1
你可以使用 Stream API 的 `Collectors.toMap` 方法,按照 `EmpType` 进行分组,并使用 `BinaryOperator.maxBy` 获取每个具有相同 `EmpType` 的分组的最新日期作为值。然后将 map 的值取出,放入一个新的 `ArrayList` 中。在这里按照 `EmpType` 进行分组,因为它包含了组号和部门信息,你需要为 `EmpType` 实现适当的 `equals` 和 `hashcode` 方法。
```java
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());
英文:
You can use Collectors.toMap
of Stream API to map by EmpType
and get the latest date for each group having the same EmpType
using BinaryOperator.maxBy
as values. Then get the values of map in new ArrayList
. Here map by EmpType
because it contains group number and department and you need proper equals and hashcode implementation for EmpType
.
List<Employee> res = new ArrayList(employees.stream()
.collect(Collectors.toMap(Employee::getEmpType, Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(Employee::getDate)))).values());
or you can create pair of group number and department like new
as key instead of
AbstractMap.SimpleEntry(e.getEmpType().getDepartment(), e.getEmpType().getGroup().getNumber())EmpType
then don't need equals and hashcode implementation
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());
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论