java – Choice between enum and final class to store options

Question:

I am developing a Java 8 application in which I need to use some settings. The settings can be different, what unites them now is that there is some representation of the setting (now this is an enumeration element), and the key and value of the setting. Settings are planned to be added to ArrayList .

Now I have a choice – whether to use an enum that implements a common interface to store settings, or try using a final class .

Specifically, I'm just starting to seriously study Java, so the question may be silly, but searching the Web in Russian and English did not give me clarity.

I give an example (abstract), as implemented now:

public interface Option {
    public String getKey();
    public String getValue();
}

public enum Option1 implements Option {
    OPTION1_VALUE_1("one"),
    OPTION1_VALUE_2("two");
    private final String key;
    private final String value;
    Option1(String val) {
        this.key = "key1";
        this.value = val;
    }
    @Override
    public String getKey() {
        return this.key;
    }
    @Override
    public String getValue() {
        return this.value;
    }
}

public enum Option2 implements Option {
    OPTION2_VALUE_1("aaa"),
    OPTION2_VALUE_2("bbb");
    private final String key;
    private final String value;
    Option2(String val) {
        this.key = "key2";
        this.value = val;
    }
    @Override
    public String getKey() {
        return this.key;
    }
    @Override
    public String getValue() {
        return this.value;
    }
}

Then I plan to use these "options" something like this:

List<Option> options = new ArrayList<Option>;
options.add(Option1.OPTION1_VALUE_1);
options.add(Option2.OPTION2_VALUE_1);
options.add(Option2.OPTION2_VALUE_2);
// А теперь, например, обходим список и выводим value
for (Option opt : options) {
    System.out.println(opt.getValue());
}

Here, actually, for these purposes I also use the interface.

In this implementation, I (and as the search showed – and many other questioners) do not like the need for each enum to redefine the getKey() and getValue() functions. It does not allow to inherit enum from a Java class.

Googling led me to the Wikipedia article " Constant interface ", from where I got the idea to implement this behavior via a final class .

I see the implementation like this:

public class Option {
    protected final String key;
    public getKey() {
        return this.key;
    }
}

public final class Option1 extends Option {
    Option() {
        this.key = "key1";
    }
    public static final String OPTION1_VALUE_1 = "one";
    public static final String OPTION1_VALUE_2 = "two";
}

public final class Option2 extends Option {
    Option() {
        this.key = "key2";
    }
    public static final String OPTION2_VALUE_1 = "aaa";
    public static final String OPTION2_VALUE_2 = "bbb";
}

I threw the code right here, without debugging, just to convey the idea. Accordingly, with this implementation, I refuse the getValue() method and get the value through the class member itself.

Basically the questions are:

  1. Is it still possible to somehow avoid the need to redefine getKey() and getValue() in the first implementation (via enums)?
  2. How adequate is the first implementation, from the position of more experienced developers?
  3. Is the idea of ​​a second implementation viable (via final class )? Is it better than using enums? Personally, it seems to me that it is more correct to use an enumeration for these purposes, but due to lack of experience, I strongly doubt such a solution.

Answer:

The first implementation can be replaced by a more successful one. In Enum, you can define your own constructors and methods. Then there is no need to create an interface, etc. It seems to me that this will be the most successful solution.

public enum Option {
    OPTION_1("key 1", "value 1"),
    OPTION_2("key 2", "value 2");

    private String key;
    private String value;

    Option(String key, String value) {
        this.key = key;
        this.value = value;
    }

    public String getKey() {
        return key;
    }

    public String getValue() {
        return value;
    }
}

UPDATE

About the use. If you need to go through all the options, then there is a standard values() method:

for (Option op : Option.values()) {
  System.out.println(op.getKey() + " - " + op.getValue());
}

If you need to operate on only a subset of the options, then use EnumSet , which provides a compact and fast data structure through an internal implementation as a bit vector.

Scroll to Top