如何使用Java Stream排序员工列表 将姓氏为Phillips的员工移至末尾
实现正确性评估
- 你的现有代码逻辑基本能实现「将包含Phillips的姓氏对应员工移到末尾」的效果,但存在两个明显问题:
- 匹配规则错误:使用
contains("Phillips")是模糊匹配,只要姓氏包含Phillips字符串就会被后置,不符合你「姓氏为Phillips」的精确匹配需求 - 性能冗余:排序操作的时间复杂度为
O(n log n),如果不需要对非Phillips员工做排序,这个开销完全可以避免
- 匹配规则错误:使用
- 额外注意:如果员工姓氏返回null,你的现有写法会触发空指针异常。
优化实现方案
下面分两种场景给出更规范高效的实现:
场景1:保留原有列表的相对顺序,不需要额外排序
这种场景下用分区收集的方案,时间复杂度仅为O(n),同时保留原列表中两类员工各自的排列顺序:
// 按是否为Phillips分区,key为false对应非Phillips员工,key为true对应Phillips员工 Map<Boolean, List<Employee>> partitionEmp = emp.stream() .collect(Collectors.partitioningBy(employee -> "Phillips".equals(employee.getSurname()))); // 合并两类列表 emp = Stream.concat(partitionEmp.get(false).stream(), partitionEmp.get(true).stream()) .collect(Collectors.toList());
如果是可变列表,也可以用更简洁的in-place操作:
List<Employee> phillipsEmp = new ArrayList<>(); // 移除所有Phillips员工存入单独列表 emp.removeIf(employee -> { boolean isPhillips = "Phillips".equals(employee.getSurname()); if (isPhillips) phillipsEmp.add(employee); return isPhillips; }); // 把Phillips员工批量追加到末尾 emp.addAll(phillipsEmp);
场景2:需要对非Phillips员工按姓氏排序
如果你的需求隐含了要对员工做排序,就优化排序规则即可,写法更易读也更严谨:
emp = emp.stream() .sorted( // 第一优先级:非Phillips员工排前面 Comparator.<Employee, Boolean>comparing(employee -> "Phillips".equals(employee.getSurname())) // 第二优先级:非Phillips员工按姓氏字典序排序,不需要可以删掉这行 .thenComparing(Employee::getSurname) ) .collect(Collectors.toList());
内容的提问来源于stack exchange,提问作者Traps_
相关产品推荐
相关产品推荐

