11
votes

I have my java enum such as: FOO("foo"), BAR("bar") ... and I have a getValue() method to return the value "foo" and "bar" of the enum and this has to be in Java.

On the other hand, I have to match this in Scala:

result match {
  case "foo" =>

I am trying to do:

result match {
  case Enum.FOO.getValue() => 

I get this error:

method getValue is not a case class constructor, nor does it have an
unapply/unapplySeq method

I'm not quite sure what is happening here since my getValue() method returns a String so why I can't use it for pattern matching? Thanks

4
If this is an enum, why just not do the case on the enum values themselves instead of their "string representation"? Otherwise you could always create a "reverse lookup" method which would return the enum value from its string representation - fge
the result is from DB and it is type String and match the string rep of the enum. I am trying to match the string value here so I don't think a reverse lookup would work, wouldn't it? Can you show me some example please? Cheers - Duc
Hold on. In your Scala code, match is a String. So far so good. What treatment is needed in each case? Can't it be a method implementation in the enum itself? - fge
@Duc: try to remove brackets: case Enum.FOO.getValue => - senia

4 Answers

14
votes

You can pattern match on Java enums, but you can't call methods in the destructuring part of the match. So this works:

j match { case Jenum.FOO => "yay"; case _ => "boo" }

if j is an instance of your Java enum (cleverly labeled Jenum).

You can however do something like this:

"foo" match {
  case s if s == Jenum.FOO.getValue => "yay"
  case _                            => "boo"
}

Or you can convert your string to the enum first:

Jenum.values.find(_.getValue == "foo") match {
  case Some(Jenum.FOO) => "yay"
  case _               => "boo"
}

(you might also want to unwrap the option first to avoid repeating Some(...) so many times).

For reference, this is the test enum I used (Jenum.java):

public enum Jenum {
  FOO("foo"), BAR("bar");

  private final String value;
  Jenum(String value) { this.value = value; }

  public String getValue() { return value; }
}
1
votes

You can't use a method call result as a pattern. Instead just write

if (result == YourEnum.FOO.getValue()) { 
  ... 
} else if {
  ...
}

or

try {
  val resultAsEnum = YourEnum.valueOf(result)

  resultAsEnum match {
    case YourEnum.FOO => ...
    ...
  }
} catch {
  case e: IllegalArgumentException => // didn't correspond to any value of YourEnum
}
1
votes

You receive the comment "method". So scala does not evaluates your function. It tried to call unapply on method.

You can implement something like (in MyEnum class):

 public static MyEnum fromText(String text) {
        for (MyEnum el : values()) {
            if (el.getValue().equals(text)) {
                return el;
            }
        }
        return null;
    }

And then

MyEnum.fromText("foo") match{
 case FOO => ..
}
0
votes

JMPL is simple java library, which could emulate some of the features pattern matching, using Java 8 features. This library can nicely work with enums.

   matches(myEnum).as(
      MyEnum.FOO,  () ->  System.out.println("FOO value");
      MyEnum.BAR,  () ->  System.out.println("BAR VALUE");
      Else.class,  () ->  System.out.println("Default value: " + data)
   );