【问题标题】:Best way to format multiple 'or' conditions in an if statement在 if 语句中格式化多个“或”条件的最佳方法
【发布时间】:2011-11-28 02:55:59
【问题描述】:

我有一个包含许多条件的 if 语句(必须检查 10 或 15 个常量以查看它们是否存在。)

而不是像这样写:

if (x == 12 || x == 16 || x == 19 || ...)

有没有办法像这样格式化

if x is [12, 16, 19]?

只是想知道是否有更简单的编码方法,感谢任何帮助。

答案非常有帮助,但有几个人要求我添加更多细节,所以我会这样做以满足他们的好奇心。我正在制作一个日期验证类,需要确保只有 30 天的月份中的天数不超过 30 天(我认为其中有 4 天),我正在编写一个 if 语句来检查这样的事情:

if (day > 30 && (month == 4 || month == 6 || month == 9 || month == 11))

我只是想知道是否有更快的方法来编写这样的代码 - 下面的许多答案都有帮助。

【问题讨论】:

  • 你能举一个更好的例子来说明你想做什么吗?也许解决方案在于思考这个问题?

标签: java syntax if-statement


【解决方案1】:

我经常使用这种模式。它非常紧凑:

// Define a constant in your class. Use a HashSet for performance
private static final Set<Integer> values = new HashSet<Integer>(Arrays.asList(12, 16, 19));

// In your method:
if (values.contains(x)) {
    ...
}

这里使用HashSet 来提供良好的查找性能——即使是非常大的哈希集也能够非常快速地执行contains()

如果性能不重要,你可以把它的要点写成一行:

if (Arrays.asList(12, 16, 19).contains(x))

但要知道它每次执行都会创建一个新的ArrayList

【讨论】:

  • if (Arrays.asList(12, 16, 19).contains(x))
  • 我宁愿使用Set 而不是List,但这对那几个元素没有任何影响。
  • @Joachim Sauer 采纳了您的想法 - 这也是一个不错的想法! HashSet 会更快
  • Using Guava: private static final ImmutableSet&lt;Integer&gt; values = ImmutableSet.of(12, 16, 19);
【解决方案2】:

要切换到这个吗?

switch(x) {
    case 12:
    case 16:
    case 19: 
        //Do something
        break;
    default:
        //Do nothing or something else..
        break;
}

【讨论】:

    【解决方案3】:

    如果可能性集是“紧凑的”(即最大值 - 最小值小于 200),您可以考虑使用查找表。如果您有像

    这样的结构,这将特别有用
    if (x == 12 || x == 16 || x == 19 || ...)
    else if (x==34 || x == 55 || ...)
    else if (...)
    

    设置一个数组,其值标识要采用的分支(上例中为 1、2、3),然后您的测试变为

    switch(dispatchTable[x])
    {
        case 1:
            ...
            break;
        case 2:
            ...
            break;
        case 3:
            ...
            break;
    }
    

    这是否合适取决于问题的语义。

    如果数组不合适,您可以使用Map&lt;Integer,Integer&gt;,或者如果您只想测试单个语句的成员资格,则可以使用Set&lt;Integer&gt;。然而,对于一个简单的if 声明来说,这已经足够强大了,所以如果没有更多的上下文,很难引导你朝着正确的方向前进。

    【讨论】:

      【解决方案4】:

      使用某种集合 - 这将使代码更具可读性并隐藏所有这些常量。一个简单的方法是使用列表:

      // Declared with constants
      private static List<Integer> myConstants = new ArrayList<Integer>(){{
          add(12);
          add(16);
          add(19);
      }};
      
      // Wherever you are checking for presence of the constant
      if(myConstants.contains(x)){
          // ETC
      }
      

      正如 Bohemian 指出的,常量列表可以是静态的,因此可以在多个地方访问。

      对于任何感兴趣的人,我的示例中的列表使用double brace initialization。自从我最近遇到它以来,我发现它非常适合编写快速而脏的列表初始化。

      【讨论】:

      • if(Arrays.asList(new int[]{12,16,19}).contains(x)){ ... }
      • @Bala 当然!无论如何,列表只是此处使用的集合的一个示例。正如其他答案之一所暗示的那样,一组可能会更好地确保常量是唯一的......或者是一个哈希表来加快查找速度等。
      【解决方案5】:

      您可以查找映射键的存在或查看它是否在集合中。

      不过,根据你实际在做什么,你可能试图错误地解决问题:)

      【讨论】:

        【解决方案6】:

        不,你不能在 Java 中做到这一点。但是,您可以编写如下方法:

        boolean isContains(int i, int ... numbers) {
            // code to check if i is one of the numbers
            for (int n : numbers) {
                if (i == n) return true;
            }
            return false;
        }
        

        【讨论】:

          【解决方案7】:

          在 Java 8 中,您可以使用原始流:

          if (IntStream.of(12, 16, 19).anyMatch(i -> i == x))
          

          但这可能会有轻微的开销(或没有),具体取决于比较的次数。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-04-01
            • 1970-01-01
            • 2015-03-28
            • 2020-01-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多