如何使用Java Streams限制用户从枚举列表中最多仅能选择2个选项
问题分析
你当前编写的代码存在几个核心逻辑问题:
- 判断条件
values().length > 3完全不符合需求:values()返回的是枚举类定义的所有枚举实例,你这里定义了3个技能,这个值永远为3,和用户实际选择的数量没有任何关联 flatMap使用场景错误:你当前的逻辑不需要做流的扁平化映射- 参数设计不匹配多选场景:单
String参数默认无法承载多个选中的技能值,一般设计为逗号分隔字符串或者可变参数更合理
完善后的实现
以下两种方案都完全基于Java Streams实现,符合你的学习需求:
方案1:入参为逗号分隔的技能字符串
适合用户传入类似HARD_WORKING,ON_TIME格式的拼接字符串:
import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import static java.util.Objects.notNull; public enum UserSkills { HARD_WORKING("HARD_WORKING"), // 注意你原拼写存在错误HARD_WORKNG,已修正 ON_TIME("ON_TIME"), HONEST("HONEST"); public final String value; UserSkills(String value) { this.value = value; } @Override public String toString() { return name() + "[" + value + "]"; } public static List<UserSkills> of(String userSkills) { notNull(userSkills, "userSkills cannot be null"); // 流式处理+结束时校验数量 return Arrays.stream(userSkills.split(",")) .map(String::trim) .filter(s -> !s.isBlank()) // 如果需要去重可在此处添加.distinct() .map(UserSkills::valueOf) .collect(Collectors.collectingAndThen(Collectors.toList(), list -> { if (list.size() > 2) { throw new IllegalArgumentException("你最多只能选择2个技能"); } return list; })); } }
方案2:入参为可变参数(更友好)
适合直接传入多个选中的技能字符串:
public static List<UserSkills> of(String... userSkills) { notNull(userSkills, "userSkills cannot be null"); return Arrays.stream(userSkills) .map(String::trim) .filter(s -> !s.isBlank()) // 如果需要去重可在此处添加.distinct() .map(UserSkills::valueOf) .collect(Collectors.collectingAndThen(Collectors.toList(), list -> { if (list.size() > 2) { throw new IllegalArgumentException("你最多只能选择2个技能"); } return list; })); }
补充说明
- 如果需要处理用户传入非法技能名的场景,可以在
map(UserSkills::valueOf)之前添加校验逻辑,避免直接抛出枚举不存在的原生异常 - 如果需要限制同一个技能不能重复选择,只需要在
map之后添加.distinct()即可
内容的提问来源于stack exchange,提问作者user9347049
相关产品推荐
相关产品推荐

