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 representationfge
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? CheersDuc
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)
   );