I have an enum I call Permission
of security permissions that matter to my application. In the database, the user may have additional permissions that are not relevant to my application. When reading the user from the database, I get a List<String>
and I want to build up a List<Permission>
, ignoring those strings that aren't values of the enum.
public enum Permission { ADMIN, USER }
List<String> plaintextAuthorities = List.of("ADMIN","USER","COFFEEMAKER")
List<Permission> appPermissions = plaintextAuthorities.stream()
.map(Permission::valueOf) // this will throw an IllegalArgumentException for 'COFFEEMAKER'
.collect(Collectors.toList());
The problem is that the map
step will throw an exception when it reaches one of the strings that doesn't correspond to a value of the enum. How can I filter
out those values so they are quietly ignored without throwing exceptions?
You can first encode the Permission
enum constants into a Set
of String and then use that in your filter
predicate to filter out invalid values. Then use a .map
operator to decode the enum constants back from the string representation only for valid values. Here's how it looks.
Set<String> strPermissionSet = Arrays.stream(Permission.values())
.map(Permission::name)
.collect(Collectors.toSet());
Set<Permission> appPermissions = plaintextAuthorities.stream()
.filter(strPermissionSet::contains)
.map(Permission::valueOf)
.collect(Collectors.toSet());
Still, you are best off declaring a static method named isValid
in your enum type so that given a string value a user can check whether it represents a valid enum constant or not. Here's how it looks.
public enum Permission {
ADMIN, USER;
private static final Set<String> strPermissions =
Arrays.stream(values())
.map(Permission::name)
.collect(Collectors.toSet());
public static boolean isValid(String val) {
return strPermissions.contains(val);
}
}
And now your client code should look like this:
Set<Permission> appPermissions = plaintextAuthorities.stream()
.filter(Permission::isValid)
.map(Permission::valueOf)
.collect(Collectors.toSet());