使用Java 8将List<String>转换为Set

7
有没有一行代码可以将字符串列表转换为枚举集合? 例如,有以下内容:
public enum MyVal {
    ONE, TWO, THREE
}

并且

List<String> myValues = Arrays.asList("ONE", "TWO", "TWO");

我想将myValues转换为一个包含与以下内容相同项的Set<MyVal>

EnumSet.of(MyVal.ONE, MyVal.TWO)

https://dev59.com/d2Ah5IYBdhLWcg3wDfkW#26731123 - buræquete
2个回答

21

可以使用 Stream<String> 将元素映射到相应的枚举值,使用映射器 MyVal::valueOf 并将其收集到由 toCollection 初始化的新 EnumSet 中,该初始化通过 noneOf 进行:

public static void main(String[] args) {
    List<String> myValues = Arrays.asList("ONE", "TWO", "TWO");
    EnumSet<MyVal> set =
        myValues.stream()
                .map(MyVal::valueOf)
                .collect(Collectors.toCollection(() -> EnumSet.noneOf(MyVal.class)));
    System.out.println(set); // prints "[ONE, TWO]"
}

如果你只对返回一个Set感兴趣,而不是一个EnumSet,你可以直接使用内置的收集器Collectors.toSet()


5
这天这种话算不算一句话? :-) ? - Thilo
5
@otonakav: 你明确要求使用EnumSet。如果任何Set都可以,你可以使用toSet(),但是那时就不需要要求一个EnumSet了。 - Holger
4
也许只有我这样想,但是你的问题标题读起来像“将List<String>转换为Java 8中的EnumSet”。很明显,“EnumSet”是关键。相信我,Tunaki知道有Collectors.toSet();所贴出的解决方案toCollection(() -> EnumSet.noneOf(MyVal.class))仅适用于你特定的问题。 - Holger
2
@Holger 实际上,我重新修改了标题,因为最初的标题是“转换为一组枚举”,而由于楼主说“包含与EnumSet相同的项”,所以我“澄清”了标题为“转换为EnumSet”...看起来这并不正确。 - Tunaki
3
我建议修改标题并扩展答案,因为当集合的类型不重要时,使用toSet()方法显然更容易。 - Holger
显示剩余4条评论

3

这里有两行话(但更短):

EnumSet<MyVal> myVals = EnumSet.allOf(MyVal.class);
myVals.removeIf(myVal -> !myValues.contains(myVal.name()));

不必将列表中存在的元素添加进去,您可以创建一个包含所有可能值的EnumSet,然后删除列表中不存在的元素。


1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - slim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接