Java中对Person对象列表按name去重并保留指定项的实现
解决方案:优化Person列表的去重与筛选
问题分析
你需要实现的逻辑是:对Person列表筛选,同名时保留年龄最大的;同名同年龄仅保留一个;其余不重名的全部保留。原嵌套循环方案时间复杂度为O(n²),且逻辑未完善,下面提供两种更高效简洁的实现方式。
方案一:使用HashMap分组处理(时间复杂度O(n))
利用HashMap的key唯一性,以name作为key,遍历过程中维护每个name对应的最大年龄Person:
import java.util.Arrays; import java.util.HashMap; import java.util.Map; public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } // 重写toString方便输出 @Override public String toString() { return name + "(" + age + ")"; } } public class Main { public static void main(String[] args) { // 修正原代码错误:new Student[4]改为new Person[4] Person[] persons = new Person[4]; persons[0] = new Person("Erik", 20); persons[1] = new Person("Bob", 21); persons[2] = new Person("Erik", 25); persons[3] = new Person("Fredrik", 20); Map<String, Person> nameToOldestPerson = new HashMap<>(); for (Person p : persons) { Person existing = nameToOldestPerson.get(p.getName()); if (existing == null) { // 该name首次出现,直接存入 nameToOldestPerson.put(p.getName(), p); } else { // 比较年龄,保留更大的 if (p.getAge() > existing.getAge()) { nameToOldestPerson.put(p.getName(), p); } // 年龄相同时不做操作,保留已存在的对象 } } // 输出结果 System.out.println("筛选结果:" + nameToOldestPerson.values()); // 输出示例:筛选结果:[Bob(21), Erik(25), Fredrik(20)] } }
方案二:使用Java Stream API(Java 8+,代码更简洁)
通过Stream的分组和聚合操作,一行代码完成筛选逻辑,可读性极强:
import java.util.Arrays; import java.util.Comparator; import java.util.Map; import java.util.stream.Collectors; // Person类同方案一,需包含toString方法 public class Main { public static void main(String[] args) { Person[] persons = new Person[4]; persons[0] = new Person("Erik", 20); persons[1] = new Person("Bob", 21); persons[2] = new Person("Erik", 25); persons[3] = new Person("Fredrik", 20); // 分组并筛选每个name下年龄最大的Person Map<String, Person> resultMap = Arrays.stream(persons) .collect(Collectors.groupingBy( Person::getName, Collectors.maxBy(Comparator.comparingInt(Person::getAge)) )) .entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, entry -> entry.getValue().get() // 取出Optional中的值 )); // 输出结果 System.out.println("筛选结果:" + resultMap.values()); } }
补充说明
- 原代码中的
Person[] persons = new Student[4];是错误的,因为未定义Student类,需改为new Person[4]。 - 若需要对结果按特定顺序(如name排序)输出,可在获取values后再进行排序:
nameToOldestPerson.values().stream() .sorted(Comparator.comparing(Person::getName)) .forEach(System.out::println);
内容的提问来源于stack exchange,提问作者ZedORYasuo
相关产品推荐
相关产品推荐

