【问题标题】:Check if list contains at least one of another - enums检查列表是否至少包含另一个 - 枚举
【发布时间】:2018-04-11 10:16:45
【问题描述】:

我有一个枚举:

public enum PermissionsEnum {
    ABC("Abc"),        
    XYZ("Xyz"),
    ....
}

然后我有一个枚举列表。我想检查我的列表是否至少有一个枚举。我目前通过迭代方法检查它。我也知道有一种方法可以使用|| 检查list.contains(enum.ABC..) || list.contains(enum.XYZ) || ...

有没有更好的方法?

This question 显示如果目标列表是字符串列表,我想获得匹配状态,如果列表是另一个枚举列表。

【问题讨论】:

  • 尝试!Collections.disjoint(list1, list2);检查list2是否包含list2形式的元素
  • “我想检查我的(枚举)列表是否至少有一个枚举”是什么意思。也许我误解了,但如果你有一个List<PermissionEnum>,那么不是所有元素都是这些枚举之一吗?除此之外,存储枚举集合的最佳方式是在 EnumSet 中,因为两次或多次拥有相同的权限是没有意义的。

标签: java enums java-8


【解决方案1】:

Collections.disjoint 返回true 如果两个指定的集合没有共同的元素。如果它返回false,那么您的列表中至少有一个枚举。

boolean contains = !Collections.disjoint(list, EnumSet.allOf(PermissionsEnum.class)));

流 API 方法可以是:

EnumSet<PermissionsEnum> set = EnumSet.allOf(PermissionsEnum.class);
boolean contains = list.stream().anyMatch(set::contains);

(类似于迭代方法,但包含并行化)

【讨论】:

  • 我会使用 EnumSet.allOf(PermissionsEnum.class) 而不是 asList(PermissionsEnum.values()),它返回一个具有 O(1) 查找的 Set,而且不需要所有值的数组副本。此外,我不会这么快插入 parallelStream(),因为列表不太可能如此庞大,以至于并行执行这样一个微不足道的操作会有好处。
【解决方案2】:

您可以使用Collections.disjoint()

使用要检查的枚举创建另一个列表,然后执行 Collections.disjoint(list, listOfEnumsToCheck)。如果没有找到任何元素,则返回 true。如果为 false,则至少存在一个元素。

我猜你甚至可以使用 Enum.values() 所以它会变成:

// Using ! to show there is at least one value
if (!Collections.disjoint(list, PermissionsEnum.values()) { 
     doStuff 
} 

【讨论】:

    【解决方案3】:

    如果你可以使用java-8

    Arrays.stream(PermissionsEnum.values()).anyMatch(list::contains);
    

    Enum#values()

    返回一个包含此枚举类型常量的数组。

    所以我们只需要将它包装到一个流中并检查列表是否包含任何值。要记住的重要一点是

    如果没有必要,anyMatch 不会评估所有元素的谓词 用于确定结果。

    换句话说,只要找到满足谓词的元素,它就可能返回true。

    显然,更有效的方法是使用EnumSet.allOf(PermissionsEnum.class)::contains,因为EnumSet.containsList.contains 更有效:

    list.stream().anyMatch(EnumSet.allOf(PermissionsEnum.class)::contains)
    

    【讨论】:

    • list.stream().anyMatch(EnumSet.allOf(PermissionsEnum.class)::contains) 更可取,因为对于所有常见的List 实现,EnumSet.containsList.contains 更有效……
    • @Holger,非常感谢您的评论,我不知道,会更新我的答案。
    【解决方案4】:

    您可以在类型安全枚举模式枚举中拥有一个静态列表来充当主列表,该列表被添加到枚举构造函数中。这样,您的主列表始终包含每个枚举中的一个,您可以与之进行比较。

    import java.util.ArrayList;
    
    public class EnumeratedEnum {
        public static final ArrayList<EnumeratedEnum> Members=new ArrayList<>();
        private final String value;
        public String getValue() {return value;}
        private EnumeratedEnum(String value) {
            this.value=value;
            Members.add(this);
        }
        public static final EnumeratedEnum EnumOne=new EnumeratedEnum("someValue");
        public static final EnumeratedEnum EnumTwo=new EnumeratedEnum("someValue2");
        public static final EnumeratedEnum EnumThree=new EnumeratedEnum("someValue3");
        public static final EnumeratedEnum EnumFour=new EnumeratedEnum("someValue4");
        public static final EnumeratedEnum EnumFive=new EnumeratedEnum("someValue5");
    }
    

    【讨论】:

      猜你喜欢
      • 2015-07-23
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-21
      • 2020-05-11
      相关资源
      最近更新 更多