【问题标题】:complex if( ) or enum?复杂的 if( ) 还是枚举?
【发布时间】:2012-06-14 11:37:30
【问题描述】:

在我的应用程序中,如果输入匹配某些特定的 20 个条目,我需要进行分支。

我想过使用枚举

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

并打开枚举常量以执行功能

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

但是输入字符串会像'is on'、'is not on'、'is before'等,单词之间没有_。 我了解到枚举不能有包含空格的常量。

可能的方法:

1、使用 if 语句比较 20 个可能的输入,给出类似长 if 语句的输入

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

2,处理输入以在单词之间插入 _,但即使其他不属于这 20 个单词的输入字符串也可以包含多个单词。

有没有更好的方法来实现这个?

【问题讨论】:

  • 在 Java 7 中你可以打开一个字符串。

标签: java enums


【解决方案1】:

您可以在枚举中定义自己版本的valueOf 方法(只是不要称它为valueOf)。

public enum State {
    IS_ON,
    IS_OFF;

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

像以前一样简单地使用它。

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

之前的 switch 语句仍然有效。

【讨论】:

  • 从这里开始并进一步简化控制流,最终出现在我发布的解决方案中。学到了很多。谢谢。 :)
【解决方案2】:

可以将枚举标识符与值分开。像这样的:

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;
    }
}

你也可以给枚举类型添加方法(方法也可以有参数),像这样:

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

在开关中使用:

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

当您获得 IS_ON 的值时,例如 System.out.println(IS_ON),它将显示 is on

【讨论】:

  • 我收到错误dateRule() in dateRule cannot be applied to (java.lang.String)。 IDE 建议是定义一个构造函数。
  • @Student 那这也是我的建议 :) 抱歉,我只发布了部分代码。我现在又添加了一些。
  • 谢谢!现在没有更多错误了。 :) 但我在System.out.println(is_on);上得到了 is_on@
  • @Student 你可能需要使用MyEnumType.IS_ON
  • 是的,我只这样做了。 dateRule.is_on 的值为 is_on。
【解决方案3】:

如果你使用的是 Java 7,你也可以在这里选择中间道路,用字符串做一个switch 语句:

switch (input) {
    case "is on":
        // do stuff
        break;
    case "is not on":
        // etc
}

【讨论】:

  • 感谢您的信息。肯定会在将来的某个时候帮助我。 :)
【解决方案4】:

你并没有真正打破这个概念,这两种解决方案都很脆弱......

看看你的语法

“是”,可以去掉,好像无处不在

"not",可选,应用 !到输出比较

在、之前、之后应用比较。

所以在空格之间进行分割。解析拆分词以确保它们存在于语法定义中,然后对传入的表达式进行逐步评估。这将允许您轻松扩展语法(无需添加“is”和“is not " 为每个组合,并保持你的代码易于阅读。

为了 switch 语句的目的而将多个条件合并为一个会导致随着时间的推移出现巨大的膨胀。

【讨论】:

    【解决方案5】:

    感谢您的建议。他们把我带到了这里。

    这与其他答案几乎相同,只是稍微简化了一点。

    总而言之,我需要将输入字符串与一组 20 个字符串进行比较

    如果他们匹配,做点什么。否则,做点别的。

    需要比较输入的静态字符串集: 开启、关闭、之前、之后等 20 个条目

    我创建了一个枚举

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

    并打开输入的格式化值

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

    我将 'input' 的格式化值复制到了 'in',这样我就可以重复使用输入,而无需再次将 '_' 替换为 ' '。

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

    问题解决了。

    参考:https://stackoverflow.com/a/4936895/1297564

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2010-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多