One approach is to use a switch - which works with String in Java 7.
// Yes, I'm passing grade and shadowing numericValue, since those properties // aren't used anywhere else in the class. public double getNumericGrade(String grade) { double numericValue = 0; switch (grade) { case "A+": case "A": numericValue = 4.0; break; case "A-": numericValue = 3.7; break; case "B+": numericValue = 3.3; break; case "B": numericValue = 3.0; break; case "B-": numericValue = 2.7; break; case "C+": numericValue = 2.3; break; case "C": numericValue = 2.0; break; case "C-": numericValue = 1.7; break; case "D+": numericValue = 1.3; break; case "D": numericValue = 1.0; break; case "F": numericValue = 0; break; default: System.out.println("Letter not in grading system"); break; } return numericValue; }
... but it reads pretty well.
Another alternative approach is to take the rules that we have about numerical estimates and write something a bit more concise.
- If the score is some letter point, it is an integer (A = 4, B = 3, C = 2, D = 1, F = 0).
- If the class has a minus attached to it, the value is the difference of the whole number and 0.3.
- If a class has a plus attached to it, the value is the sum of the whole number and 0.3.
Here is a solution that uses these rules. It may read a little more verbose and perhaps not everything that differs from the switch, but this is another way to write it.
public double getNumericGradeRefactored(String grade) { Map<Character, Double> gradeMap = new HashMap<Character, Double>(){{ put('A', 4.0); put('B', 3.0); put('C', 2.0); put('D', 1.0); put('F', 0.0); }}; // split result char[] gradeParts = grade.toCharArray(); double result = gradeMap.get(gradeParts[0]); if(gradeParts.length > 1) { switch(gradeParts[1]) { case '+': result += 0.3; break; case '-': result -= 0.3; break; } } return result; }
source share