缩小多个IF语句

时间:2016-01-20 20:08:33

标签: java if-statement

我是Java的新手,我正在尝试创建一个程序,允许我输入一个月,然后输入一天。如果一个月内的某一天有效(I.e.二月28日有效,29则无效),我希望它结束​​。我已经使它工作了,但我每个月都使用了12个IF语句,它看起来太乱了,而且代码太多了。 任何人都可以提出一种更好的冷凝方法吗?

require 'httparty'

4 个答案:

答案 0 :(得分:4)

面向对象的惯用方法:

  

忽略这是一个已经处理过的天真的稻草人问题域   通过JDK中的类以及JodaTime和其他现有的类   解决方案,这是一个如何消除密集的例子   一般情况下复杂的if/else if/elseswitch条件。

这实现了Strategy Pattern的变体,专门用于替换if/elseif/elseEnums的{​​{1}}语句。对于像这样的狭窄领域,它也同样适用。

此解决方案利用Interfaces实现Predicate的功能,并在实际的Month枚举实例中提供Predicate逻辑。使用isValidDay()界面而不是自定义Predicate方法也允许if/else if/else与其他人进行合成或链接。

这消除了所有嘈杂的重复import javax.annotation.Nonnull; import javax.annotation.Nullable; import com.google.common.base.Predicate; public class Q34909522 { private static enum Month implements Predicate<Integer> { JANUARY(31), FEBRUARY(28), MARCH(31), APRIL(28), MAY(31), JUNE(30), JULY(31), AUGUST(31), SEPTEMBER(30), OCTOBER(31), NOVEMBER(30), DECEMBER(31); public final int daysInMonth; private Month(final int daysInMonth) { this.daysInMonth = daysInMonth; } @Override public boolean apply(@Nullable final Integer input) { return input != null && input >= 1 && input <= this.daysInMonth; } } public static void main(@Nonnull final String[] args) { /** Scanner excluded for brevity */ for (final Month m : Month.values()) { for (int i = 0; i <= 33; i++) { if (!m.apply(i)) { System.out.format("%d is not a valid day of the month for %s (%d)", i, m, m.daysInMonth ); System.out.println(); } } } } } 语句,同时也允许您遵守cyclomatic complexity

DRY Principle

0 is not a valid day of the month for JANUARY (31)
32 is not a valid day of the month for JANUARY (31)
33 is not a valid day of the month for JANUARY (31)
0 is not a valid day of the month for FEBRUARY (28)
29 is not a valid day of the month for FEBRUARY (28)
30 is not a valid day of the month for FEBRUARY (28)
31 is not a valid day of the month for FEBRUARY (28)
32 is not a valid day of the month for FEBRUARY (28)
33 is not a valid day of the month for FEBRUARY (28)
truncated for brevity ...

输出:

February

闰年:

  

增强此功能以确定The error message that I am getting is ==> default: Attempting graceful shutdown of VM... The following SSH command responded with a non-zero exit status. Vagrant assumes that this means the command failed! shutdown -h now Stdout from the command: Stderr from the command: stdin: is not a tty bash: line 2: syntax error near unexpected token `||' bash: line 2: `export SSH_AUTH_SOCK= || ||' 是否为闰年   为读者练习,因为这是一个很好的记录   问题和超出了要求的范围   问题,这具体指示2月的 28有效,   29无效

答案 1 :(得分:0)

你可以在这里做很多事情,但我的头脑中还有一对......

1)您只有3个不同的案例 - 28天,30天和31天,因此您可以将这些案例分解为3个if语句,如下所示:

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

2)将值存储在数组中并进行查找:

int[] daysInMonth = new int[] { 31, 28, 31, etc... };
if (day > daysInMonth[month]) {
    ....
}

3)使用内置的时间/日期功能为您处理。

答案 2 :(得分:0)

首先,创建一个包含每月天数的数组。

int[ ] daysInMonth = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

然后,将day的值与数组中的相应位置进行比较:

if (day > daysInMonth[month]) {
    System.out.print("This is not a valid day of the month");
}

剩下的唯一额外检查是检查二月是否是闰年:

boolean isLeapYear = (year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))

答案 3 :(得分:0)

Java核心库已经进行了日期解析。

直接通过SimpleDateFormat提供文本输入,并将lenient设置为false。它将为所有无效值抛出异常。

private SimpleDateFormat sdf = new SimpleDateFormat("yyyy MM dd");
sdf.setLenient(false);
try
{
    sdf.parse("2016 " + args[0] + " " + args[1]);
}
....

除了不重新发明轮子之外,这也迫使您明确选择年份,这对闰年日期的合法性有重大影响。