决定和方法

时间:2013-08-25 03:50:33

标签: java if-statement

书中的问题:

编写一个程序,将字母等级翻译成数字等级。字母等级为ABCDF,可能后跟+。他们的数值是43210。没有F+F–+将数值增加0.3将数值减少0.3。但是,A+的值为4.0

输入字母成绩:B-数值为2.7。 使用方法getNumericGrade的等级成绩。

所以我的问题是:我知道我的代码是正确的,我可以运行它。但我很好奇是否有这个代码的快捷方式或更好的版本,使它看起来更专业,更容易阅读。任何建议或例子都将非常感激。

代码:

import java.util.Scanner;


public class grade
{
    private double numericValue = 0;
    private String grade = "";

    public grade()
    {

        Scanner in = new Scanner(System. in );
        System.out.print("Enter Grade: ");
        grade = in .nextLine();
    }

    public double getNumericGrade()
    {

        if (grade.equals("A+") || grade.equals("A"))
        {
            numericValue = 4.0;
        }
        else if (grade.equals("A-"))
        {
            numericValue = 3.7;
        }
        else if (grade.equals("B+"))
        {
            numericValue = 3.3;
        }
        else if (grade.equals("B"))
        {
            numericValue = 3.0;
        }
        else if (grade.equals("B-"))
        {
            numericValue = 2.7;
        }
        else if (grade.equals("C+"))
        {
            numericValue = 2.3;
        }
        else if (grade.equals("C"))
        {
            numericValue = 2.0;
        }
        else if (grade.equals("C-"))
        {
            numericValue = 1.7;
        }
        else if (grade.equals("D+"))
        {
            numericValue = 1.3;
        }
        else if (grade.equals("D"))
        {
            numericValue = 1.0;
        }
        else if (grade.equals("F"))
        {
            numericValue = 0;
        }
        else
        {
            System.out.println("Letter not in grading system");
        }
        return numericValue;
    }
}

6 个答案:

答案 0 :(得分:6)

您可以单独定义映射和规则:

public static enum Grade {

    // Letter grades are A, B, C, D, and F
    // Their numeric values are 4, 3, 2, 1, and 0

    A(4),B(3),C(2),D(1),F(0);

    public final double score;

    private Grade(double d) {
        this.score = d;
    }

    // Grades are possibly followed by + or –
    // There is no F+ or F–
    // a + increases the numeric value by 0.3, a – decreases it by 0.3
    // However, an A+ has value 4.0

    public double getModifiedScore(char sign) {
        switch (sign) {
            case '+':
                return score + (score < 4 && score > 0 ? 0.3 : 0);
            case '-':
                return score + (score > 0 ? -0.3 : 0);
            default:
                throw new IllegalArgumentException("Invalid sign");
        }
    }
}

然后只使用它们(例子假设您已经验证了输入):

public static double getNumericGrade(String s){
    Grade g = Grade.valueOf(s.substring(0, 1));
    if(s.length() > 1){
        return g.getModifiedScore(s.charAt(1));
    }else {
        return g.score;
    }
}

答案 1 :(得分:5)

我会使用查找表:

private final static Map<String,Double> gradeLookup = 
   new HashMap<String, Double>();

gradeLookup.put("A-", 3.7);

numericValue = gradeLookup.get(grade);

另一个好的选择是switch语句,从Java 7开始,它最终适用于Strings。

这两个选项都为您提供内置输入验证,因此用户无法输入“G”或“F +”或“foo”等内容。

答案 2 :(得分:1)

使用Map将字符(在本例中为A .. DF)映射到相应的值(4 .. {{ 1}})。

处理输入时:

  • 如果它只有一个字符长,只需在地图中查找字符即可。
  • 如果最后有0+,请查找第一个字符并适当处理第二个字符(根据您发布的规则,记住处理特殊情况,例如{{ 1}})。

您可以尝试这样的事情:

-

答案 3 :(得分:1)

一种方法是使用switch - 它与Java 7中的String一起使用。

// 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;
}

......但这看起来非常冗长。

另一种替代方法是采用我们对数字等级的规则,并写一些更简洁的东西。

  • 如果等级是某个字母点,则为整数(A = 4,B = 3,C = 2,D = 1,F = 0)。
  • 如果等级附有减号,则该值为整数与0.3的差值。
  • 如果成绩附加了一个加号,则该值是整数与0.3的总和。

这是一个使用这些规则的解决方案。它可能看起来更冗长,可能与开关没有什么不同,但它是写它的另一种方式。

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;

}

答案 4 :(得分:0)

我会单独处理'+'或' - '。

检查字母,然后如果它包含'+'或' - ',则适当地加或减等级值。

编辑:就个人而言,我更喜欢switch-case到if if-elseif语句,但任何一个都可以运行得很好。

答案 5 :(得分:0)

除了@Thilos关于如何存储实际数据的建议之外,我想补充一点,在这种情况下,您不希望同时存储两者,在这种情况下,String和{{1数据的版本,除非性能非常关键。

虽然现在看起来不是很重要,但在很多情况下,你会冒失去同步的风险,即int说一件事,而String说另一件事,你遇到了因此而产生的错误。

你的构造函数不应该提示输入,除非这变得非常普遍..采用int更清晰。