2014-02-08 113 views
0

我正在写一个简单的方法,将用户的成绩作为输入并计算成绩平均值。这里是我的代码:为什么此代码无法按预期工作?

public static double calculateGPA(){ 
    Scanner in = new Scanner(System.in); 

    double totalGradePoints = 0; // total grade points 
    int numClasses = 0; // total classes completed 
    boolean doneInput = false; // returns true when use is done inputting grades 

    System.out.println("Enter all your grades (A,B,C,D,F) and enter 'done' if you are done entering your grades."); 
    while (!doneInput) {  
     String grade = in.next(); 

     if (grade == "A") { 
     totalGradePoints += 4; 
     numClasses++; 
     } else if (grade == "B") { 
     totalGradePoints += 3; 
     numClasses++; 
     } else if(grade == "C") { 
     totalGradePoints += 2; 
     numClasses++; 
     } else if(grade == "D") { 
     totalGradePoints += 1; 
     numClasses++; 
     } else if(grade == "F") { 
     numClasses++; 
     } else { 
     doneInput = true; 
     } //end if - else-if - else statement 
    }//end while loop 
    double unwtGPA = (totalGradePoints/numClasses); 
    return unwtGPA; 
} 

当我测试的方法,我只能输入一个档次,没有增加的变量,可有人告诉我,什么是错的代码?

回答

11

问题是使用==而不是equals进行字符串比较。 ==比较参考,这是非常不可能相等。更改为

if(grade.equals("A")){ 
     totalGradePoints += 4; 
     numClasses++; 
    }else if(grade.equals("B")){ ... 

它应该工作。有关详细说明,请参阅this answer

作为一个很好的做法,建议始终使用静态字符串作为主叫等于上,以防止NPE对象:

if("A".equals(grade)){ 
     totalGradePoints += 4; 
     numClasses++; 
    }else if("B".equals(grade)){ ... 

如果您使用的是Java 7,你也可以做一个switch声明用绳子(虽然这个人会抛出一个NPE如果等级为null):

switch(grade) { 
    case "A": 
     totalGradePoints += 2; 
     numClasses++; 
     break; 
    case "B": 
     ... 
} 

最后,因为你将只有一个字母为整数,最好的解决办法是将它们转换成char和值在A和之间做totalGradePoints += ('D' - grade.charAt(1)) + 1。因此,类似的规定将最简单的阅读IMO:

while (true) {   
    final String input = in.next(); 
    if(input == null || input.isEmpty()) 
     break; 

    final char grade = input.charAt(0); 
    if(grade >= 'A' && grade <= 'D') { 
     totalGradePoints += ('D' - grade) + 1; 
    } else if(grade == 'F') { 
     // no gradepoints for 'F' 
    } else { 
     break; 
    } //end if - else-if - else statement 

    ++numClasses; 
} //end while loop 
+2

或甚至更好的是交换机。 –

+0

运营商可能会超载吗? –

+2

@huseyintugrulbuyukisik不是在Java中,它不是。 –

0

你的失败是使用==运算符来检查字符串平等。字符串是对象,因此在这种情况下将会检查对象标识(缺省为引用检查)。

使用equals使由字符检查一个字符,像这样:

if(grade.equals("A")){ 
3

的问题是,你正在使用==比较字符串,当你应该使用s.equals("...")==运算符检查身份,并且字符串不保证具有相同的标识(可能有几个对象表示完全相同的字符串)。 equals()方法比较字符串的内容的平等性而不是对象的身份。

我会写更是这样的:

Scanner in = new Scanner(System.in); 

double totalGradePoints = 0; // total grade points 
int numClasses = 0; // total classes completed 

System.out.println("Enter all your grades (A,B,C,D,F) and" 
     + " write 'done' when you have finished"); 

while (true) { 
    String input = in.next(); 
    if (input.equals("done")) { 
     break; 
    } 
    if (input.equals("A")) { 
     totalGradePoints += 4; 
    } else if (input.equals("B")) { 
     totalGradePoints += 3; 
    } else if (input.equals("C")) { 
     totalGradePoints += 2; 
    } else if (input.equals("D")) { 
     totalGradePoints += 1; 
    } else if (!input.equals("F")) { 
     System.err.println("Invalid input: " + input); 
     continue; 
    } 
    numClasses++; 
} 
double unweightedGPA = (totalGradePoints/numClasses); 
System.out.println(unweightedGPA); 

while(true)环路与break(退出循环)和continue(跳回到循环的开始)是更地道的Java。我上面版本的主要好处是不存在numClasses++行的重复。

你甚至可以使循环更加简洁,更简单地使用地图,它会返回一个分值的等级或null为无效等级改变等级分:

Map<String, Integer> gradePoints = new HashMap<String, Integer>() {{ 
    put("A", 4); 
    put("B", 3); 
    put("C", 2); 
    put("D", 1); 
    put("F", 0); 
}}; 

String input; 
while (!(input = in.next()).equals("done")) { 
    Integer points = gradePoints.get(input); 
    if (points == null) { 
     System.err.println("Invalid input: " + input); 
     continue; 
    } 
    totalGradePoints += points; 
    numClasses++; 
} 

这是还值得指出的是,在你的代码和这个页面的所有答案中,如果你没有输入任何等级,你将得到一个零分(产生NaN),所以你可能想考虑处理这个优雅。

+0

我不是java专家,但是如果某个地图中的键不通过,地图的行为如何。 – epsilonhalbe

+0

如果映射找不到密钥,则映射返回'null'。因此,行'if(points == null)...' –

+0

谢谢澄清 - 我认为你应该在*答案中提到这个*,然而一个优雅的解决方案+1 – epsilonhalbe

相关问题