在 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<Integer> 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<Integer,Integer>
,或者如果您只想测试单个语句的成员资格,则可以使用Set<Integer>
。然而,对于一个简单的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 语句中格式化多个“或”条件的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章