在 if 语句中格式化多个“或”条件的最佳方法

Posted

技术标签:

【中文标题】在 if 语句中格式化多个“或”条件的最佳方法【英文标题】:Best way to format multiple 'or' conditions in an if statement 【发布时间】: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))

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

【问题讨论】:

你能举一个更好的例子来说明你想做什么吗?也许解决方案在于思考这个问题? 【参考方案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))

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

【讨论】:

以上是关于在 if 语句中格式化多个“或”条件的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

liunx 下的shell语句 if [ ! -d /$1/$2/$3/ ]是啥意思?

理论 : shell编程之条件语句————理论讲解

Cmake中的条件判断if/elseif/else

Shell脚本之if条件语句

针对IF语句测试范围值数组的最佳方法

我正在尝试将我的多个数组方法调用简化为 if 语句或更简单的基于条件的语句