5

In my app, I need to branch out if the input matches some specific 20 entries.

I thought of using an enum

public enum dateRule { is_on, is_not_on, is_before,...}

and a switch on the enum constant to do a function

switch(dateRule.valueOf(input))
{
  case is_on : 
  case is_not_on :
  case is_before :
  .
  .
  .
  // function()
  break;
}

But the input strings will be like 'is on', 'is not on', 'is before' etc without _ between words. I learnt that an enum cannot have constants containing space.

Possible ways I could make out:

1, Using if statement to compare 20 possible inputs that giving a long if statement like

if(input.equals("is on") ||
   input.equals("is not on") || 
   input.equals("is before") ...)   { // function() }

2, Work on the input to insert _ between words but even other input strings that don't come under this 20 can have multiple words.

Is there a better way to implement this?

unholysampler
  • 17,141
  • 7
  • 47
  • 64
aradhak
  • 836
  • 1
  • 9
  • 22

5 Answers5

3

It is possible to seperate the enum identifier from the value. Something like this:

public enum MyEnumType
{
    IS_BEFORE("is before"),
    IS_ON("is on"),
    IS_NOT_ON("is not on")

    public final String value;

    MyEnumType(final String value)
    {
        this.value = value;
    }
}

You can also add methods to the enum-type (the method can have arguments as well), something like this:

public boolean isOnOrNotOn()
{
    return (this.value.contentEquals(IS_ON) || this.value.contentEquals(IS_NOT_ON));
}

Use in switch:

switch(dateRule.valueOf(input))
{
    case IS_ON: ...
    case IS_NOT_ON: ...
    case IS_BEFORE: ...
}

And when you get the value of IS_ON like for example System.out.println(IS_ON) it will show is on.

Simon Forsberg
  • 13,086
  • 10
  • 64
  • 108
  • I get the error `dateRule() in dateRule cannot be applied to (java.lang.String)`. The IDE suggestion is to define a constructor. – aradhak Jun 14 '12 at 11:54
  • @Student Then that is my suggestion too :) Sorry about that, I only posted a partial code. I have added some more now. – Simon Forsberg Jun 14 '12 at 12:01
  • Thanks! No more error now. :) But I get is_on on `System.out.println(is_on);` – aradhak Jun 14 '12 at 12:30
  • @Student You might need to use `MyEnumType.IS_ON` for that. – Simon Forsberg Jun 14 '12 at 17:11
  • Yes, I did that only. dateRule.is_on has value is_on. – aradhak Jun 15 '12 at 04:35
  • @Student Are you sure you have written this part correctly? ` IS_BEFORE("is before"), IS_ON("is on"), IS_NOT_ON("is not on")`. The value within the parentesis should be the value that the enums have. – Simon Forsberg Jun 15 '12 at 06:11
  • Does case matter? If not, then yes I have is_on("is on"), is_not_on("is not on"), is_before("is before") etc in the enum. – aradhak Jun 15 '12 at 07:15
  • @Student when you print out the value print out `MyEnumType.is_on.value` also, don't forget that when you specify the enums use `is_on("is on")` and so on to specify them. – Simon Forsberg Jun 15 '12 at 11:59
3

You can define your own version of valueOf method inside the enum (just don't call it valueOf).

public enum State {
    IS_ON,
    IS_OFF;

    public static State translate(String value) {
        return valueOf(value.toUpperCase().replace(' ', '_'));
    }
}

Simply use it like before.

State state = State.translate("is on");

The earlier switch statement would still work.

adarshr
  • 61,315
  • 23
  • 138
  • 167
  • Started from here and on further simplifying the control flow ended up in the solution I posted. Learnt a lot. Thanks. :) – aradhak Jun 15 '12 at 05:59
1

If you're using Java 7, you can also choose the middle road here, and do a switch statement with Strings:

switch (input) {
    case "is on":
        // do stuff
        break;
    case "is not on":
        // etc
}
fivedigit
  • 18,464
  • 6
  • 54
  • 58
0

You're not really breaking the concept up enough, both solutions are brittle...

Look at your syntax

"is", can remove, seems to be ubiquitous

"not", optional, apply a ! to the output comparison

on, before, after, apply comparisons.

So do a split between spaces. Parse the split words to ensure they exist in the syntax definition and then do a step-by-step evaluation of the expression passed in. This will allow you to easily extend the syntax (without having to add an "is" and "is not" for each combination and keep your code easy to read.

Having multiple conditions munged into one for the purposes of switch statements leads to huge bloat over time.

Jeff Watkins
  • 6,343
  • 16
  • 19
0

Thanks for the suggestions. They guided me here.

This is almost same as other answers, just a bit simplified.

To summarize, I need to compare the input string with a set of 20 strings and

if they match, do something. Else, do something else.

Static set of strings to which input needs to be compared : is on,is not on,is before,is after, etc 20 entries

I created an enum

public enum dateRules
{
   is_on
   ,is_not_on
   ,is_before
   ,is_after
   .
   .
   .
}

and switching on formatted value of input

if(isARule(in = input.replace(" ","_"))
{
   switch(dateRule.valueOf(in))
   {
      case is_on,
      case is_not_on,
      case is_before, ...
   }
}

I copied the formatted value of 'input' to 'in' so that I can reuse input without another replace of '_' with ' '.

private static boolean isARule(String value)
  {
    for(dateRule rule : dateRule.values())
    {
      if(rule.toString().equals(value))
      {
        return true;
      }
    }
    return false;
  }

Problem solved.

Reference : https://stackoverflow.com/a/4936895/1297564

Community
  • 1
  • 1
aradhak
  • 836
  • 1
  • 9
  • 22