0

As you can see below, I have three declared enums, and each class has a method called getEnumByName() which revives a name and returns the enum which has that name.

I have noticed that I am duplicating the same functionality of this method on each enum.

Is there any way to change this method to a generic one, which receives the given enum's type and does the same logic?

public class Enums {

    public enum A {
        APPLY("Apply", "abcde");

        private String id;
        private String name;

        A(String name, String id) {
            this.name = name;
            this.id = id;
        }

        public static A getEnumByName(String name) throws Exception {
            for (A instance : A.values()) {
                if (instance.getName().equals(name)) return instance;
            }
            throw new Exception("There is no operations matches :" + name);
        }

        public String getName() {
            return name;
        }

        public String getId() {
            return id;
        }
    }

    public enum B {
        APPLY("Apply", "1"),
        SAVE("Save", "2"),
        REVERT("Revert", "2"),
        REVERT_CHILD("Revert->Revert", "4"),
        REVERT_APPLY("Revert->Revert Apply", "5"),
        SYNC("Sync", "6"),
        OPERATIONS("Operations", "7"),
        IMPORT("Import", "8"),
        EXPORT("Export", "9"),
        DIFF("Diff", "10");

        private String id;
        private String name;

        B(String name, String id) {
            this.name = name;
            this.id = id;
        }

        public static B getEnumByName(String name) throws Exception {
            for (B instance : B.values()) {
                if (instance.getName().equals(name)) return instance;
            }
            throw new Exception("There is no operations matches :" + name);
        }

        public String getName() {
            return name;
        }

        public String getId() {
            return id;
        }
    }

    public enum C {
        UPDATE_POLICES("Update Policies", "A"),
        OPERATIONS("Operations", "B"),
        IMPORT_CONFIGURATION_FILE("Import Configuration File", "c"),
        EXPORT_CONFIGURATION_FILE("Export Configuration File", "d"),
        EXPORT_LOG_SUPPORT_FILE("Export Log Support File", "f"),
        EXPORT_TECHNICAL_SUPPORT_FILE("Export Technical Support File", "g"),
        UPDATE_SOFTWARE_VERSION("Update Software Version", "g"),
        UPDATE_SECURITY_SINGAUTES("Update Security Signatures", "h"),
        DIFF("Diff", "k");

        private String id;
        private String name;

        C(String name, String id) {
            this.name = name;
            this.id = id;
        }

        public static C getEnumByName(String name) throws Exception {
            for (C instance : C.values()) {
                if (instance.getName().equals(name)) return instance;
            }
            throw new Exception("There is no operations matches :" + name);
        }

        public String getName() {
            return name;
        }

        public String getId() {
            return id;
        }
    }
}
entpnerd
  • 10,049
  • 8
  • 47
  • 68
Moaad
  • 117
  • 1
  • 4
  • 13
  • 3
    Be aware that an enum instance already has a `name`, which is the enum constant itself. You are overloading the word `name` for your own purposes, which will confuse future maintainers, and I'd advise choosing a different name for `name`. – Jim Garrison Feb 06 '18 at 06:22

2 Answers2

1

One option is to have them all implement a common interface called, say, Named:

interface Named {
    String getName();
}

Now you can create a generic method like this:

static <E extends Enum<E> & Named> E getEnumByName(Class<E> enumClass, String name) throws Exception {
    return Arrays.stream(enumClass.getEnumConstants())
            .filter(e -> e.getName().equals(name))
            .findAny()
            .orElseThrow(() -> new Exception("There is no operations matches :" + name));
}

And call it like this:

A a = getEnumByName(A.class, "Apply");
shmosel
  • 49,289
  • 6
  • 73
  • 138
1

Consider using the static Enum valueOf() method. You can call it generically as follows or just call it directly. See this answer for details.

static <E extends Enum<E>> E getEnumByName(Class<E> enumClass, String name) {
    return Enum.valueOf(enumClass, name);
}
entpnerd
  • 10,049
  • 8
  • 47
  • 68
  • @shmosel I didn't want to add a method, just advocate for the `valueOf()` method, but the question was asking for it. So... – entpnerd Feb 06 '18 at 06:19
  • But it's not at all what OP asked for. – shmosel Feb 06 '18 at 06:20
  • This would work if the OP was looking to match the enum constant, but s/he's not. The task is to match the member `name`. The overloading of the `name` is unfortunate. – Jim Garrison Feb 06 '18 at 06:21