Java中ArrayList存储的自定义对象字符串字段比较不生效问题咨询
问题根因
- 字符串比较错误使用
==运算符:Java中==作用于引用类型时,对比的是对象的内存地址而非实际存储的内容。toLowerCase()执行后会生成全新的String对象,即便转小写后内容完全一致,两个对象也处于堆内存的不同地址,==比对自然返回false。仅当输入大小写与原数据完全一致时,可能触发JVM字符串常量池的复用机制,两个字符串指向同一内存地址,才会偶然匹配成功,该逻辑不具备稳定性。 - 注释中的双重校验逻辑存在笔误:原有注释里的
getName().toLowerCase()比对对象错误写为email.toLowerCase(),即便修正比较运算符也会出现逻辑错误。
修复方案
基础修复
使用String类自带的equalsIgnoreCase()方法直接进行不区分大小写的内容比对,无需手动转小写,代码更简洁。循环部分修正后示例如下:
// 仅校验邮箱是否重复 for(int i=0; i<custArr.size(); i++) { if (custArr.get(i).getEmail().equalsIgnoreCase(email)) { System.out.println("Error! User already exists in the system"); break; // 匹配到后直接跳出循环,避免无效遍历 } } // 需同时校验姓名+邮箱重复的修正逻辑 for(int i=0; i<custArr.size(); i++) { if (custArr.get(i).getName().equalsIgnoreCase(name) && custArr.get(i).getEmail().equalsIgnoreCase(email)) { System.out.println("Error! User already exists in the system"); break; } }
优化方案
如果数据量较大、需要频繁执行判重操作,可选用以下两种优化方式:
- 使用Stream流简化代码:
boolean isDuplicate = custArr.stream() .anyMatch(cust -> cust.getEmail().equalsIgnoreCase(email)); if (isDuplicate) { System.out.println("Error! User already exists in the system"); }
- 重写Customer类的
equals()和hashCode()方法,改用HashSet存储实例,判重时间复杂度可从O(n)降至O(1),大幅提升效率。
内容的提问来源于stack exchange,提问作者k_plan
相关产品推荐
相关产品推荐

