如何在Java中的if/else语句中使用数字范围

6

我通过一系列的讲解和练习来学习Java,其中一个练习是创建一个程序,根据不同的分数范围(0-29、30-34、35-39、40-44、45-49、50-60),显示相应的数字成绩(0-5)。

System.out.println("Type the points [0-60]: ");
double points = reader.nextDouble();
reader.nextLine();
if (points < 29) {
    System.out.println("Grade: FAILED.");
} else if (points <= 34) {
    System.out.println("Grade: 1.");
} else if (points <= 39) {
    System.out.println("Grade: 2.");
} else if (points <= 44) {
    System.out.println("Grade: 3.");
} else if (points <= 49) {
    System.out.println("Grade: 4.");
} else if (points >= 50) {
    System.out.println("Grade: 5.");
}

该程序的工作原理是由于命令之间的重叠而给出正确的成绩,但是否有任何方法可以创建一系列数字或字符串来满足if / else语句的条件呢?例如,如果输入的数字在40-44之间等等。由于我是新手,因此希望能得到详细的答案。


你可以在if语句中反转控制以使其更清晰。但是首先我建议你创建一个新变量来保存成绩,然后在测试后使用System.out.println("Grade: "+gradeVar); - itwasntme
只有使用“整数”输入,您的范围才是严格连续的。例如,对于两个范围“0-29,30-34”(假设包含边界),29.5 应该得到什么等级? - Andy Brown
最后的 else if 应该改为 elseif (points >= 50) 没有任何作用。 - Andreas
6个回答

6

将数字除以五,并用十二个字符串组成一个数组表示等级的文本表示:

private static final String GRADE_FAILED = "FAILED";
private static final String GRADE_1 = "1";
private static final String GRADE_2 = "2";
private static final String GRADE_3 = "3";
private static final String GRADE_4 = "4";
private static final String GRADE_5 = "5";

private static String GradeStr[] = new {
    GRADE_FAILED // 0..4
,   GRADE_FAILED // 5..9
,   GRADE_FAILED // 10..14
,   GRADE_FAILED // 15..19
,   GRADE_FAILED // 20..24
,   GRADE_FAILED // 25..29
,   GRADE_1      // 30..34
,   GRADE_2      // 35..39
,   GRADE_3      // 40..44
,   GRADE_4      // 45..49
,   GRADE_5      // 50..54
,   GRADE_5      // 55..59
,   GRADE_5      // 60..64 // Only sixty matters
};

System.out.println("Grade:"+GradeStr[points/5]+".");

如果你需要更细致的控制,可以扩大数组、除以更小的数字或者完全跳过除法,然后设置与需要打印的成绩对应的位置中的常量。这样可以避免使用条件语句。
重要声明:当选项数量较少(最多一百左右)时,该方法效果最佳。若问题适用于此方法,则该方法是迄今为止最快的方法。在许多情况下,这也是最易于阅读的方法。

处理不同增量的数字是最后一个段落所讨论的问题。这段代码可能存在一个偏差问题,它只是一个“如何用数组替换if-else链”的示例原则。 - Sergey Kalinichenko
@Andreas,请不要再制造麻烦了:正如所述,我们有60个数字(即六十个数字,而不是一千个数字)。大小往往非常重要。这是其中之一。 - Sergey Kalinichenko
同意。但是你错过了我第一条评论的一部分。0-60是61个数字。你需要额外添加一行 , GRADE_5 // 60..64,否则60分将会抛出IndexOutOfBoundsException异常,并且在(points+1)中你可能不应该有那个+1。 - Andreas
抱歉,在您看到评论后我进行了修改。+1 不应该存在,应该只使用 GradeStr[points/5]。这样就能完美地解决问题,无需任何免责声明。;-) - Andreas
@Andreas 免责声明是关于扩大范围,而不是关于偏移一个。拥有额外的元素仍然是必要的,因为成绩使用人类计数,所以它们一直持续到60。 - Sergey Kalinichenko
显示剩余3条评论

5
您可以使用一个NavigableMap,最常用的是TreeMap。下面使用的方法是floorEntry。引用Javadoc

返回与小于或等于给定键的最大键相关联的键值映射;如果没有这样的键,则返回null

注意:您的代码在29个边界上缺少一个=符号,并且points值应该是一个整数。 更改为使用等级(0-5),而不是问题中使用的字符串。
// Grade boundary is lower-inclusive (grade is 0-60)
TreeMap<Integer, Integer> gradeMap = new TreeMap<>();
gradeMap.put( 0, 0); //  0–29
gradeMap.put(30, 1); // 30–34
gradeMap.put(35, 2); // 35–39
gradeMap.put(40, 3); // 40–44
gradeMap.put(45, 4); // 45–49
gradeMap.put(50, 5); // 50+

System.out.println("Type the points [0-60]: ");
int points = reader.nextInt();
reader.nextLine();
int grade = gradeMap.floorEntry(points).getValue();
System.out.println("Grade: " + grade);

3
如果您想测试数字是否介于某些值之间,请在if语句中使用逻辑运算符AND进行测试,例如:

如果您想测试数字是否介于某些值之间,请在if语句中使用逻辑运算符AND进行测试:

if(points>=40 && points <=45)

为了更好地理解,我建议您像这样进行控制反转:

要获得更多的讲解,我建议您进行控制反转,就像这样:

    int grade;
    if(points >49){
        grade=5;
    }else if(points >44){
        grade=4;
    }else if(points >39){
        grade=3;
    }else if(points >34){
        grade=2;
    }else if(points >29){
        grade=1;
    }else{
        grade=0;

  }
    System.out.println("Gr: "+grade); //grade=0 = not passed

这与问题有什么不同?我不明白为什么改变顺序会使它更清晰。--- 你确实改成了符合0-5分级别的文本,很好,但除此之外呢? - Andreas
每个条件都检查点数是否大于(不使用 <> 两者)。它也可以采用其他方式,在最后一个 else 中应用 grade=5。但我认为这比将许多条件应用于单个 if 更容易阅读。您和 dasblinkenlight 的解决方案非常好,如果有人想避免使用 if - itwasntme
好的,问题代码应该在最后一个使用else而不是else if,并且在第29行缺少一个=符号,但是你的代码也不好,第一个测试使用>=,其他测试使用>,我认为在最后使用else,而不是默认初始值,会更加清晰。 - Andreas
取决于上下文,但如果你在任何测试中得到了0,你就会知道这里的其他内容是无用的 :) 是的,我大多数情况下在if语句中使用else,并且通常将我的变量作为类字段或地图的一部分,就像你建议的那样,但是这样我就知道未初始化变量的值。 - itwasntme
@Andreas 根据您的建议进行了编辑,我考虑了一下性能,以确保在确定输出后不再进行另一个测试语句。不过,这仍然取决于上下文。 - itwasntme
grade初始化为0,然后将其更改为5,比使用else更糟糕,但是鉴于不要在需要之前对代码进行性能调整的普遍口号(请参见这些引用:https://en.wikipedia.org/wiki/Program_optimization#Quotes),两者在性能方面都是可以接受的。---顺便说一句:您缺少一个结束括号。;-) - Andreas

1
如果您想检查一个数字是否在两个值之间,您可以在if语句中使用and:
if (points >= 40 && points <= 44) {
    System.out.println("Grade: 3.");
}

1
如果您想在if语句中检查范围,可以这样做:
if(points >= 0 && points <= 29)

这可以通过使用 &&(与)运算符将条件组合在一起来实现。
但实际上,在任何if语句中都不需要检查范围。 按照您当前的做法即可满足要求。

1
我认为您可能正在寻找的是:

if( points<=44 && points>=40 ) 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接