我们有一个ArrayList。它包含重复的员工对象,只有年龄不同,但名称和ID将相同。因此,在删除重复项时,我们必须让员工保持最大年龄并删除所有其他重复项。这是一位采访者在其中一次采访中提出的问题之一。
我试着解决这个问题。它给了我正确的结果,但我不确定我的方法,因为我在equals方法中更改对象的状态。有没有其他方法可以解决这个问题? 下面的代码片段: -
package practice;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
class Employee {
private int id;
private String name;
private int age;
Employee(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
return (31*(name.hashCode()) + 31);
}
@Override
public boolean equals(Object obj) {
if ((obj instanceof Employee)) {
if (((Employee)obj).getId() == this.id && (((Employee)obj).getName().equalsIgnoreCase(this.name))) {
if(this.age > ((Employee)obj).getAge()) {
((Employee)obj).setAge(this.age);
}
return true;
} else
return false;
} else
return false;
}
}
public class ListDuplicateRemoval {
public static List<Employee> removeDuplicates(List<Employee> employees) {
Set<Employee> set = new HashSet<>();
for (int i = 0; i < employees.size(); i++) {
set.add(employees.get(i));
}
/*for (int i = 0; i < set.size(); i++) {
System.out.println(set.iterator().next().getAge());
}*/
employees.removeAll(employees);
employees.addAll(set);
return employees;
}
public static void main(String[] args) {
Employee e1 = new Employee(1, "Mike", 20);
Employee e2 = new Employee(1, "Mike", 21);
List <Employee> list = new ArrayList<>();
list.add(e1);
list.add(e2);
removeDuplicates(list);
System.out.println(list.size());
System.out.println(list.get(0).getAge());
}
}
答案 0 :(得分:1)
这个解决方案真的很糟糕。 equals永远不应该修改它所比较的对象的状态。
创建一个包含唯一标识员工的信息的类,以及正确覆盖equal()和hashCode()的信息。然后使用包含这些身份验证信息的Map作为密钥,并使用年龄最大的员工作为值。然后获取值并将其设为列表:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
class Employee {
private int id;
private String name;
private int age;
Employee(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
int getId() {
return id;
}
String getName() {
return name;
}
int getAge() {
return age;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
class DuplicateRemoval {
public static void main(String[] args) {
List<Employee> employeeList = Arrays.asList(
new Employee(1, "Joe", 23),
new Employee(2, "Joe", 23),
new Employee(1, "Joe", 21),
new Employee(1, "Jane", 22),
new Employee(1, "Jane", 20)
);
Map<EmployeeKey, Employee> map = employeeList.stream().collect(
Collectors.toMap(e -> new EmployeeKey(e.getId(), e.getName()),
Function.identity(),
(e1, e2) -> e1.getAge() > e2.getAge() ? e1 : e2)
);
List<Employee> result = new ArrayList<>(map.values());
System.out.println("result = " + result);
}
private static class EmployeeKey {
private int id;
private String name;
EmployeeKey(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
EmployeeKey that = (EmployeeKey) o;
return id == that.id &&
Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}
}
答案 1 :(得分:0)
实施Comparator<Employee>
compare
方法考虑到年龄。equals
方法忽略年龄。使用equals
来识别重复项。
使用compare
确定要保留的副本。