Java 8中如何基于大小写不同的String属性去除对象列表重复项?
解决Java 8中基于大小写不敏感的String属性去重列表问题
我懂你的需求啦——要对包含Employee对象的列表去重,判断重复的依据是name属性,但得忽略大小写差异(比如"John"和"john"算同一个)。下面给你两种实用的实现方案,都用Java 8的Stream API来完成:
方案一:保持原列表顺序的去重(推荐)
这种方法会保留列表中第一个出现的重复项,同时完全维持原有的元素顺序,适合大多数场景:
首先补全你的Employee类(确保getName()方法完整):
public class Diggu { static class Employee { // 改成static,否则外部无法直接实例化 private int id; private String name; public Employee(int id, String name) { this.id = id; this.name = name; } 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; } // 可选:重写toString方便调试 @Override public String toString() { return "Employee{id=" + id + ", name='" + name + "'}"; } } public static void main(String[] args) { List<Employee> employees = Arrays.asList( new Employee(1, "Alice"), new Employee(2, "alice"), new Employee(3, "Bob"), new Employee(4, "BOB"), new Employee(5, "Charlie") ); // 核心去重逻辑 Set<String> seenNames = new HashSet<>(); List<Employee> uniqueEmployees = employees.stream() .filter(employee -> { // 将name转为小写(或大写)后加入集合,判断是否已存在 String normalizedName = employee.getName() != null ? employee.getName().toLowerCase() : null; return seenNames.add(normalizedName); }) .collect(Collectors.toList()); // 输出结果 uniqueEmployees.forEach(System.out::println); } }
逻辑说明:
- 用
HashSet记录已经处理过的name(统一转成小写,消除大小写差异) filter方法中,seenNames.add()会返回true当且仅当该元素是第一次被加入集合,这样就过滤掉了后续重复的元素- 额外处理了
name为null的情况,避免空指针异常
方案二:基于排序的去重
如果不关心原列表的顺序,或者希望结果按name排序,可以用TreeSet配合自定义比较器:
List<Employee> uniqueEmployees = employees.stream() .collect(Collectors.toCollection(() -> new TreeSet<>( // 按name大小写不敏感比较 Comparator.comparing(Employee::getName, String.CASE_INSENSITIVE_ORDER) ))) .stream() .collect(Collectors.toList());
逻辑说明:
TreeSet会根据指定的比较器判断元素是否相等:当两个Employee的name大小写不敏感相等时,比较器返回0,TreeSet会认为它们是同一个元素,自动去重- 最终结果会按
name的自然排序(忽略大小写)输出,比如"Alice"会在"Bob"前面
两种方案都能满足你的需求,根据是否需要保留原顺序来选择就好~
内容的提问来源于stack exchange,提问作者fatherazrael
相关产品推荐
相关产品推荐

