我是 Java 的新手,我正在尝试编写一个允许我输入月份然后输入日期的程序。我希望它在一个月内的一天有效时结束(即 2 月 28 日有效,29 日无效)。我让它工作了,但是我每个月都使用了 12 个 IF 语句,它看起来太乱了,而且代码太多了。 谁能建议一种更好的方法来浓缩它?
import java.util.Scanner;
public class Calender {
public static void main(String[] args) {
int month=0;
int day=0;
Scanner in = new Scanner (System.in);
do {
System.out.print("Enter a month [1..12]: ");
month=in.nextInt();
//continue;
} while (month > 12);
//System.out.println ("This is not a valid month.");
do {
System.out.print("Enter a day [1..31]: ");
day=in.nextInt();
} while (day > 31);
if (day > 31 && month == 1) {
System.out.print("This is not a valid day of the month");
}
if (day > 31 && month == 3) {
System.out.print("This is not a valid day of the month");
}
if (day > 31 && month == 5) {
System.out.print("This is not a valid day of the month");
}
if (day > 31 && month == 7) {
System.out.print("This is not a valid day of the month");
}
if (day > 31 && month == 8) {
System.out.print("This is not a valid day of the month");
}
if (day > 31 && month == 10) {
System.out.print("This is not a valid day of the month");
}
if (day > 31 && month == 12) {
System.out.print("This is not a valid day of the month");
}
if (day > 30 && month == 4) {
System.out.print("This is not a valid day of the month");
}
if (day > 30 && month == 6) {
System.out.print("This is not a valid day of the month");
}
if (day > 30 && month == 9) {
System.out.print("This is not a valid day of the month");
}
if (day > 30 && month == 11) {
System.out.print("This is not a valid day of the month");
}
if (day > 28 && month == 2) {
System.out.print("This is not a valid day of the month");
}
}
}
最佳答案
惯用的面向对象方法:
Ignoring that this is a naive strawman problem domain already handled by classes in the JDK as well as JodaTime and other existing solutions, this is intended to be an example of how to eliminate dense and complex
if/else if/else
andswitch
conditions in general.
这实现了 Strategy Pattern
的变体,它专门设计用于替换具有高 cyclomatic complexity 的 if/elseif/else
语句。 .它同样适用于像这样的狭窄领域。
此解决方案利用 Enums
的能力来实现 Interfaces
并在实际的 Month
中提供 Predicate
逻辑> 枚举实例。使用 Predicate
接口(interface)而不是自定义 isValidDay()
方法还允许将 Predicate
与其他方法组合或链接。
这消除了所有嘈杂的重复 if/else if/else
语句,并允许您遵守 DRY Principle
Q34909522.java
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();
}
}
}
}
}
输出:
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 ...
闰年:
Enhancing this to determine if
February
is a leap year is an exercise for the reader since this is a trivial well documented problem and outside the scope of the requirements as stated in the question, that specifically instructs that 28 in February is valid, 29 is invalid.
关于java - 压缩多个 IF 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34909522/