
本文详解如何在 java 的 arraylist 中对自定义对象(如 address)的字符串字段进行不区分大小写的模糊匹配搜索,重点解决 `contains()` 因大小写敏感导致“anth”与“anth”无法匹配的问题,并提供健壮、可复用的实现方案。
在使用 ArrayList
进行基于 organizationName 字段的搜索时,若直接调用 String.contains() 方法,默认是严格区分大小写的。例如 "Anth".contains("anth") 返回 false,这正是问题中搜索 "Anth" 和 "anth" 均无结果的根本原因。更关键的是,原始代码中存在两个严重隐患:
- 空指针风险:d.getOrganizationName().toLowerCase() != null 先调用了 toLowerCase() 再判空——但若 getOrganizationName() 返回 null,此行会立即抛出 NullPointerException,根本执行不到后续逻辑;
- 逻辑错误:条件中仅对 search 调用了 toLowerCase(),却未对 organizationName 的比较值统一转小写,导致大小写转换不一致,匹配必然失效。
✅ 正确做法是:先判空,再统一转小写后比对。以下是修复后的 searchAddress 方法:
@Override
public List searchAddress(String search) {
// 若搜索关键词为空或空白,可选择返回空列表或全部数据(按需调整)
if (search == null || search.trim().isEmpty()) {
return new ArrayList<>(list); // 或 return Collections.emptyList();
}
List results = new ArrayList<>();
String searchLower = search.toLowerCase().trim();
for (Address address : list) {
String orgName = address.getOrganizationName();
// 先确保 orgName 非 null,再安全转小写并匹配
if (orgName != null && orgName.toLowerCase().contains(searchLower)) {
results.add(address);
}
}
return results;
}? 进阶建议(提升性能与可维护性):
立即学习“Java免费学习笔记(深入)”;
- ✅ 使用 Java 8+ Stream API 可使代码更简洁:
return list.stream() .filter(a -> a.getOrganizationName() != null && a.getOrganizationName().toLowerCase().contains(search.toLowerCase().trim())) .collect(Collectors.toList()); - ✅ 对高频搜索场景,可预处理 organizationName 为小写缓存(如新增 getOrganizationNameLower() 方法),避免重复调用 toLowerCase();
- ⚠️ 注意:toLowerCase() 受 Locale 影响(如土耳其语中 I → i 的特殊规则),如需绝对一致性,建议显式指定 toLowerCase(Locale.ENGLISH);
- ? 若 Address 类由外部输入构建,建议在构造器或 setter 中对 organizationName 做非空校验,从源头降低 NPE 风险。
总结:不区分大小写的搜索核心在于统一大小写 + 安全空值处理。切勿在未判空前调用字符串方法,也勿遗漏任一参与比较的字符串的大小写标准化。遵循此原则,即可稳定支持 "ANTH"、"anth"、"Anth" 等任意大小写组合的模糊匹配。










