Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to check if list contains at least one of an enum

I have an enum :

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

And then I have a list of Strings. I want to check if my list has at least one of the enums. I currently check it by an iterative approach. I also know there is a way to do it by using || checking list.contains(enum.ABC..) || list.contains(enum.XYZ) || ....

Is there a better way to do it?

like image 682
S.Dan Avatar asked Apr 10 '18 06:04

S.Dan


People also ask

Can you use == for enum?

Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant.

How do you know if an enum contains a specific value?

Enum. IsDefined is a check used to determine whether the values exist in the enumeration before they are used in your code. This method returns a bool value, where a true indicates that the enumeration value is defined in this enumeration and false indicates that it is not.

How do you check if at least one enum value is equal to a variable within an IF condition?

if (randomValue & (Values. Value1 | Values. Value2) > 0) { //... } You can use an array (nicer if you have predefined sets of values you want to search for).

How do I check if a string contains enum?

The EnumUtils class has a method called isValidEnum which takes as parameters the name of the Enum class and the String to be matched. It returns a boolean true if the String is contained in the Enum class, and a boolean false otherwise.


2 Answers

A List<String> never contains a PermissionsEnum value.

The condition list.contains(enum.ABC) || list.contains(enum.XYZ) is not going to be working.

Instead, you could map PermissionsEnum.values() to a Stream<String> and call Stream#anyMatch on it:

boolean result = Arrays.stream(PermissionsEnum.values())
                       .map(PermissionsEnum::getValue)
                       .anyMatch(list::contains);

*I assumed that constructor parameter is accessible by the getValue method.


In case the list is large (a few iterations over it might take a lot of time) we could optimise the previous snippet a bit and iterate over the list once:

Set<String> values = Arrays.stream(PermissionsEnum.values())
                           .map(PermissionsEnum::getValue)
                           .collect(Collectors.toSet());

boolean result = list.stream().anyMatch(values::contains);
like image 151
Andrew Tobilko Avatar answered Oct 01 '22 07:10

Andrew Tobilko


You can do it easily in an iterative way with a for loop.

boolean contains = false;
for (PermissionsEnum permission : PermissionsEnum.values()) {
    if (list.contains(permission.getName())) {
        contains = true;
        break;
    }
}

Or you can use Collections.disjoint() like this:

Set<String> permissionsNames = Stream.of(PermissionsEnum.values())
                                     .map(PermissionsEnum::getName())
                                     .collect(Collectors.toSet());

boolean contains = !Collections.disjoint(list, permissionsNames);

PS: getName() must retrieve the constructor value.

like image 44
Aleksandr Avatar answered Oct 01 '22 06:10

Aleksandr