6
if (isProductDeliverable) {
  REQUIRED_FIELDS = Arrays.asList(new String[] { Fields.NAME, Fields.EMAIL, Fields.ADDRESS });
} else {
  REQUIRED_FIELDS = Arrays.asList(new String[] { Fields.NAME, Fields.EMAIL });
}

Instead of this, I want to have a predefined enum with two fields - REQUIRED_FIELDS_FOR_DELIVERABLE_PRODUCTS and REQUIRED_FIELDS_FOR_DOWNLOADABLE_PRODUCTS

I know the theory of enums but I've never used them so I cant figure out a way how to do this.

Or maybe a way to ask for the required fields by passing this "isProductDeliverable" boolean and get the correct array of fields?

3
  • Did you look at the recommended tutorial? Commented Feb 22, 2015 at 12:05
  • 1
    Have you tried anything yet? Note that it's unconventional to have a variable with a shouty name like REQUIRED_FIELDS... Commented Feb 22, 2015 at 12:06
  • Yes I've seen the tutorial but I dont know how to apply it in this particular case. Commented Feb 22, 2015 at 12:09

2 Answers 2

19

Enums can have data and behaviour much like classes. Something like this should work...

public enum RequiredFields {
    REQUIRED_FIELDS_FOR_DELIVERABLE_PRODUCTS( Fields.NAME, Fields.EMAIL, Fields.ADDRESS ),
    REQUIRED_FIELDS_FOR_DOWNLOADABLE_PRODUCTS( Fields.NAME, Fields.EMAIL );

    private List<String> fields;
    private RequiredFields(String... fields){
        this.fields = Arrays.asList(fields);
    }
    public List<String> getFields(){
        return fields;
    }
}

Further improvement:

In above code, the fields property is still mutable. Someone could do REQUIRED_FIELDS_FOR_DELIVERABLE_PRODUCTS.getFields().add(..) which would beat the whole purpose of having the enum in the first place.

Better implementation for the constructor would be:

private RequiredFields(String... fields){
    this.fields = ImmutableList.copyOf(fields); //com.google.common.collect.ImmutableList
}
Sign up to request clarification or add additional context in comments.

6 Comments

So whenever I need the list of fields, I just do REQUIRED_FIELDS_FOR_DOWNLOADABLE_PRODUCTS.getFields(), right? Is there a way to pass "isDeliverable" to the enum so that it returns the correct type, so I can avoid an if else construct?
'Which enum to return' logic is probably better kept outside the enum, in the class where you are using the enum.
Ok but is it at least possible?
Collections.unmodifiableList(Arrays.asList(fields)) works too and has no external dependencies.
@J.K. Enum is very similar to a standard class, you can just add a static method with an if/else.
|
0

For creating immutable list of objects, from Java 9 you can use List.of static method. So you can create something like:

   Enum1("a","b"),
   Enum2("c","d")
   private String fields;
   EnumClassName(String...args) {
    this.fields = List.of(args);
   }
  }

In the calling method you can call like list = Enum1.fields; Hoping this clears your understanding.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.