我是Java的新手,我正在尝试创建一个程序,允许我输入一个月,然后输入一天。如果一个月内的某一天有效(I.e.二月28日有效,29则无效),我希望它结束。我已经使它工作了,但我每个月都使用了12个IF语句,它看起来太乱了,而且代码太多了。 任何人都可以提出一种更好的冷凝方法吗?
require 'httparty'
答案 0 :(得分:4)
忽略这是一个已经处理过的天真的稻草人问题域 通过JDK中的类以及JodaTime和其他现有的类 解决方案,这是一个如何消除密集的例子 一般情况下复杂的
if/else if/else
和switch
条件。
这实现了Strategy Pattern
的变体,专门用于替换if/elseif/else
高Enums
的{{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]);
}
....
除了不重新发明轮子之外,这也迫使您明确选择年份,这对闰年日期的合法性有重大影响。