2

I have an enum:

public enum Status{
   A("A"),
   B("B"),
   C("C"),
   D("D"),
   E("E")
}

A,B,C are in one category and D&E are a different category. Now when I get a string, I want to decide which category it falls in. Basically,

String s;
if   s.equals( Status.A.toString()) || s.equals(Status.B.toString()) || s.equals( Status.C.toString()) 
            return 1; 

        else return 2;

Now, this is manageable with 5 letters. If I have 26 letters, the number of if conditions will be unmanageable. Is there a better way to write this?

user1692342
  • 5,007
  • 11
  • 69
  • 128

2 Answers2

5

Rather than deciding the category in the code, store it in the enum itself. You are not limited to a single stored attribute; you can have as many as you wish.

Change the constructor to take the category in addition to the letter, and store it in the enum:

public enum Status {
    A("A", 1),
    B("B", 1),
    C("C", 1),
    D("D", 2),
    E("E", 2);
    private String name;
    private int category;
    public String getName() { return name; }
    public int getCategory() { return category; }
    Status(String name, int category) {
        this.name = name;
        this.category = category;
    }
}

Now it is very clear which enum belongs to what category, because categories are assigned declaratively rather than algorithmically.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • I would suggest there to make the category an enum itself instead of using raw ints. – GhostCat Mar 29 '17 at 03:28
  • @GhostCat Absolutely! Assuming that category has some meaning (as opposed to being, say, an indexer into some array) using an `enum` for `category` would be a good idea. – Sergey Kalinichenko Mar 29 '17 at 03:29
  • @dasblinkenlight I like this solution. However, is there no way to take advantage of the fact that a letter is mapped to the value. so say letter B = 2. Is there a way to do something like if(a.value() < s.value() < e.value()) return category1 ? – user1692342 Mar 29 '17 at 05:12
  • @user1692342 You can definitely rely on `enum`s ordering: `.ordinal()` is always there, so you can compare them as needed. However, as soon as you do that, the definition of category becomes implicit in code again, rather than being declarative, and it also becomes dependent on the declaration order of `enum` values, which is less than ideal. – Sergey Kalinichenko Mar 29 '17 at 11:26
2

How about you maintain a list of enums per category and then compare your string with the enums in a category list? See the following example.

    List<Status> category1 = new ArrayList<Status>();
    category1.add(Status.A);
    category1.add(Status.B);
    category1.add(Status.C);
    List<Status> category2 = new ArrayList<Status>();
    category2.add(Status.D);
    category2.add(Status.E);

    for(Status e : category1) {
        if(s.equals(e.toString()))
            return true;
    }

    for(Status e : category2) {
        if(s.equals(e.toString()))
            return true;
    }

    return false;
VHS
  • 9,534
  • 3
  • 19
  • 43