枚举与字符串列表过滤的常见方法包括传统for循环和StreamAPI。将枚举值转换为Set集合,可使contains操作性能提升至O(1)。需注意枚举字段使用final修饰、防范空指针异常,并确保JDK版本兼容(如Java8+支持Stream及EnumSet优化)。
用枚举过滤字符串列表
作者:技术拾光
时间:2026-06-18
浏览:630
文章目录
在实际开发中,字符串列表与枚举类型的“对齐”操作几乎是每天都要遇到的需求——用户提交的配置项、外部系统传来的数据,总得与预定的业务类型比对之后才能放心向下处理。例如,你手头有一个材料类型列表 ["window", "door", "room", "kitchen", "bedroom"],而枚举只认 "window" 和 "door",那就需要从大列表中把合法的项目提取出来。

首先,需要将枚举类定义规范——Java 中使用 enum 关键字,类名首字母大写,常量全部大写。下面这个修正后的版本可以直接使用:
public enum Type {
WIN("window"),
DOOR("door");
private final String type;
Type(String type) {
this.type = type;
}
public String getType() {
return type;
}
}
方式一:传统 for 循环——清晰直观,稳定可靠
如果对性能敏感,或者项目仍在使用 JDK 7 甚至更早版本,那么传统 for 循环是最稳妥的选择。代码虽然稍长,但每一步逻辑都很明确:
ListmatType = Arrays.asList("window", "door", "room", "kitchen", "bedroom"); List matchingTypes = new ArrayList<>(); for (String candidate : matType) { for (Type type : Type.values()) { if (type.getType().equals(candidate)) { matchingTypes.add(candidate); break; // 匹配后立即退出内层循环,节省时间 } } } // 结果:["window", "door"]
两层循环嵌套,内层一旦匹配便 break 退出,逻辑简单,不会产生意外结果。
方式二:Stream API——函数式风格,一行搞定
如果已经使用 Java 8 及以上版本,Stream 方案会让你感叹代码的简洁。先将枚举转换为字符串流,再过滤,最后收集,一气呵成:
ListmatchingTypes = Arrays.stream(Type.values()) .map(Type::getType) .filter(matType::contains) .collect(Collectors.toList());
代码量大幅减少,可读性也不差——只要熟悉函数式编程,一眼就能看出处理目的。
几个容易踩中的陷阱
- 枚举中的
type字段务必添加final修饰,防止后续意外修改引发问题。 - 如果原始列表数据量很大,而枚举项只有两三个,建议先将枚举值转换为
Set,这样contains的复杂度降为 O(1),性能提升明显:
SetvalidTypes = Arrays.stream(Type.values()) .map(Type::getType) .collect(Collectors.toSet()); List matchingTypes = matType.stream() .filter(validTypes::contains) .collect(Collectors.toList());
- 还需注意
String.equals()的空安全——如果matType中包含null,传统循环会抛出空指针异常,Stream 方案也需要额外过滤。幸运的是,枚举的getType()永远不会返回null(构造时已赋值),因此只需确保传入列表中的元素非空。
总结一下:Stream 方案更现代,代码更为紧凑;而使用 Set 优化后,面对大数据量时扩展性更佳。具体选择哪种方式,需要根据项目实际情况综合考虑可读性、性能以及 JDK 版本等因素。
实用工具推荐
电子包浆
使用 ›绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
图片压缩
使用 ›选择画质和输出格式,预览压缩前后的大小。