我正在编写一个简单的方法,将成绩作为用户的输入并计算成绩点平均值。这是我的代码:
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;
}
当我测试方法时,我只能输入一个等级而且没有任何变量递增,有人能告诉我代码有什么问题吗?
答案 0 :(得分:11)
问题在于使用==
而不是equals
进行字符串比较。 ==
比较了不太可能相等的引用。改为
if(grade.equals("A")){
totalGradePoints += 4;
numClasses++;
}else if(grade.equals("B")){ ...
它应该有效。有关详细说明,请参阅this answer。
作为一种好的做法,建议始终使用静态字符串作为调用equals的对象以防止NPE:
if("A".equals(grade)){
totalGradePoints += 4;
numClasses++;
}else if("B".equals(grade)){ ...
如果您使用的是Java 7,您还可以使用字符串执行switch
语句(但如果成绩为null,则会抛出一个NPE):
switch(grade) {
case "A":
totalGradePoints += 2;
numClasses++;
break;
case "B":
...
}
最后,由于您只将一个字母转换为整数,因此最佳解决方案是将它们转换为char,将A
和D
之间的值转换为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
答案 1 :(得分: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),所以你可能想要思考关于优雅地处理。
答案 2 :(得分:0)
您的失败是使用==
运算符检查字符串是否相等。字符串是对象,因此在这种情况下将检查对象标识(默认为引用检查)。
使用equals
进行字符检查,如下所示:
if(grade.equals("A")){