在 EnumSet 和布尔值数组之间转换

Posted

技术标签:

【中文标题】在 EnumSet 和布尔值数组之间转换【英文标题】:Convert between EnumSet and array of boolean values 【发布时间】:2016-11-16 21:49:16 【问题描述】:

我有一个EnumSet 并希望在布尔基元数组之间来回转换。如果效果更好,我可以使用 List 而不是数组,和/或 Boolean 对象而不是布尔基元。

enum MyEnum  DOG, CAT, BIRD; 
EnumSet enumSet = EnumSet.of( MyEnum.DOG, MyEnum.CAT ); 

我想在另一端得到一个如下所示的数组:

[TRUE, TRUE, FALSE]

这里的这个问题与Convert an EnumSet to an array of integers 类似。区别:

布尔值或Boolean 与整数(显然) 我希望枚举的所有成员都被表示,TRUE 代表包含在 EnumSet 中的每个枚举元素,FALSE 代表从 EnumSet 中排除的每个元素。另一个问题的数组仅包含在 EnumSet 中找到的项目。 (更重要的是)

【问题讨论】:

【参考方案1】:

要做到这一点,你基本上会写

MyEnum[] values = MyEnum.values(); // or MyEnum.class.getEnumConstants()
boolean[] present = new boolean[values.length];
for (int i = 0; i < values.length; i++) 
  present[i] = enumSet.contains(values[i]);

另一个方向,从上面创建的布尔数组present 到下面创建的enumSet_

EnumSet<MyEnum> enumSet_ = EnumSet.noneOf ( MyEnum.class );  // Instantiate an empty EnumSet.
MyEnum[] values_ = MyEnum.values ();
for ( int i = 0 ; i < values_.length ; i ++ ) 
    if ( present[ i ] )   // If the array element is TRUE, add the matching MyEnum item to the EnumSet. If FALSE, do nothing, effectively omitting the matching MyEnum item from the EnumSet.
        enumSet_.add ( values_[ i ] );
    

【讨论】:

谢谢。我对更高级的 lambda/streams 语法很好奇,但最好展示简单但确定的老式语法。 我冒昧地编写了从数组到 EnumSet 的另一个方向的示例代码。此代码基于我的一些工作代码,但经过修改以匹配您的示例。所以如果我在这里发布的代码是正确的,我不是 100%。 @BasilBourque,QuarterHour 是什么? @AndrewTobilko 哎呀,QuarterHour 是来自this Answer of mine 的另一个问题的复制粘贴结转错误。现已修复。【参考方案2】:

目前,我没有看到比这更好的解决方案

Boolean[] b = Arrays.stream(MyEnum.values()).map(set::contains).toArray(Boolean[]::new);

使用zipboolean 基元数组中获取EnumSet

MyEnum[] enums = zip(Arrays.stream(MyEnum.values()), Arrays.stream(b),
    (e, b) -> b ? e : null).filter(Objects::nonNull).toArray(MyEnum[]::new);

【讨论】:

contains 方法不会遍历整个枚举。 contains 方法在两个 EnumSet 实现中被覆盖,JumboEnumSet 和 RegularEnumSet。【参考方案3】:

在 Java 8 中你可以这样做

List<Boolean> present = Arrays.stream(MyEnum.values()).map(enumSet::contains).collect(Collectors.toList());

反过来,你可以做这样的事情

IntStream.range(0, present.size()).filter(present::get).mapToObj(i -> MyEnum.values()[i]).
    collect(Collectors.toCollection(() -> EnumSet.noneOf(MyEnum.class)));

【讨论】:

以上是关于在 EnumSet 和布尔值数组之间转换的主要内容,如果未能解决你的问题,请参考以下文章

如何使用javascript将字符串数组转换为布尔值? [复制]

如何在Java中将二维布尔数组转换为一维字节数组?

JS 类型转换

无法将“查询”类型的值转换为预期的条件类型“布尔”

字符转详细与初步了解for循环

返回的布尔值转换为布尔值