问题
I have 3 enumerator classes in my application. All 3 classes have 2 duplicate methods that we want available in every enum that we implement.
public static List<String> supported(){
return Arrays.asList([[EnumClass]].values())
.stream().map(Enum::name).collect(Collectors.toList());
}
public static boolean contains(String value){
boolean response = false;
try {
response = value != null ? [[EnumClass]].valueOf(value.trim().toUppercase()) != null : false;
} catch (Exception e){
LOGGER.error("ERROR: {}", e);
}
return response;
}
The only part of these methods that changes is the EnumClass which is the class of each enum.
The first method will print all the possible values for the enum class and the second method will return true/false if the given String can be made into the enum class.
I tried to implement an Interface that implemented these methods, but I can't use values() because it's not part of the Enum API. I can't relate the methods to each class specifically because the methods are public static. I can't create a custom class and extend Enum to extend that since Java doesn't support multiple inheritance.
For the meanwhile I have my code working, but the duplication really bothers me and I feel like it can be way better. If we continue to add new enumerators then the duplication will just get worse.
回答1:
You cannot have the Enum class implement an interface, but you can keep a static reference to an object on each enum, and those objects can implement a common interface. This will reduce the amount of duplication.
public static class EUtils<E extends Enum<E>> {
private final E[] values;
private Function<String,E> valueOf;
public EUtils(E[] values, Function<String,E> valueOf) {
this.values = values;
this.valueOf = valueOf;
}
public List<String> supported(){
return Arrays.asList(values)
.stream().map(Enum::name).collect(Collectors.toList());
}
public boolean contains(String value){
boolean response = false;
try {
response = value != null ? valueOf.apply(value.trim().toUpperCase()) != null : false;
} catch (Exception e){
e.printStackTrace();
}
return response;
}
}
private enum Directions {
LEFT,
RIGHT;
public static EUtils<Directions> enumUtils = new EUtils<>(Directions.values(),Directions::valueOf);
}
public static void main(String[] args) {
System.out.println(Directions.enumUtils.contains("LEFT"));
System.out.println(Directions.enumUtils.contains("X"));
}
来源:https://stackoverflow.com/questions/48198823/how-to-re-use-duplicate-code-with-enums-in-java-8