这些switch语句有哪些替代方案?

时间:2022-07-01 16:03:48

Just whipped up this extremely simple GPA calculator, wondering how I would use a loop to avoid the huge blocks of switch statements? I am very new to Java and just looking for some advice, any other ways to improve the program are greatly appreciated. Thanks in advance, guys!

这是一个非常简单的GPA计算器,我想知道如何用一个循环来避免大量的switch语句?我对Java很陌生,只是在寻找一些建议,任何其他改进程序的方法都非常感谢。提前谢谢,伙计们!

package helloPackage;
import javax.swing.JOptionPane;

public class GradePointAverage {

public static void main(String[] args) {
    System.out.println("Welcome to the GPA calculator! Please enter your GPA into the popup window to find your GPA.");

    String firstClassInput = JOptionPane.showInputDialog(null,"Please enter your grade for your first class: (A+, A, A-, B+, etc.)");
    String firstClass = firstClassInput.toUpperCase();
    String secondClassInput = JOptionPane.showInputDialog(null,"Please enter your grade for your second class: (A+, A, A-, B+, etc.)");
    String secondClass = secondClassInput.toUpperCase();
    String thirdClassInput = JOptionPane.showInputDialog(null,"Please enter your grade for your third class: (A+, A, A-, B+, etc.)");
    String thirdClass = thirdClassInput.toUpperCase();
    String fourthClassInput = JOptionPane.showInputDialog(null,"Please enter your grade for your fourth class: (A+, A, A-, B+, etc.)");
    String fourthClass = fourthClassInput.toUpperCase();
    String fifthClassInput = JOptionPane.showInputDialog(null,"Please enter your grade for your fifth class: (A+, A, A-, B+, etc.)");
    String fifthClass = fifthClassInput.toUpperCase();

    double firstGrade = 0.0;
    double secondGrade = 0.0;
    double thirdGrade = 0.0;
    double fourthGrade = 0.0;
    double fifthGrade = 0.0;

    switch (firstClass){
    case "A+": firstGrade = 4.33;
        break;
    case "A": firstGrade = 4.00;
        break;
    case "A-": firstGrade = 3.67;
        break;
    case "B+": firstGrade = 3.33;
        break;
    case "B": firstGrade = 3.00;
        break;
    case "B-": firstGrade = 2.67;
        break;
    case "C+": firstGrade = 2.33;
        break;
    case "C": firstGrade = 2.00;
        break;
    case "C-": firstGrade = 1.67;
        break;
    case "D+": firstGrade = 1.33;
        break;
    case "D": firstGrade = 1.00;
        break;
    case "D-": firstGrade = .67;
        break;
    case "F": firstGrade = 0.0;
        break;
    }

    switch (secondClass){
    case "A+": secondGrade = 4.33;
        break;
    case "A": secondGrade = 4.00;
        break;
    case "A-": secondGrade = 3.67;
        break;
    case "B+": secondGrade = 3.33;
        break;
    case "B": secondGrade = 3.00;
        break;
    case "B-": secondGrade = 2.67;
        break;
    case "C+": secondGrade = 2.33;
        break;
    case "C": secondGrade = 2.00;
        break;
    case "C-": secondGrade = 1.67;
        break;
    case "D+": secondGrade = 1.33;
        break;
    case "D": secondGrade = 1.00;
        break;
    case "D-": secondGrade = .67;
        break;
    case "F": secondGrade = 0.0;
        break;
    }
    switch (thirdClass){
    case "A+": thirdGrade = 4.33;
        break;
    case "A": thirdGrade = 4.00;
        break;
    case "A-": thirdGrade = 3.67;
        break;
    case "B+": thirdGrade = 3.33;
        break;
    case "B": thirdGrade = 3.00;
        break;
    case "B-": thirdGrade = 2.67;
        break;
    case "C+": thirdGrade = 2.33;
        break;
    case "C": thirdGrade = 2.00;
        break;
    case "C-": thirdGrade = 1.67;
        break;
    case "D+": thirdGrade = 1.33;
        break;
    case "D": thirdGrade = 1.00;
        break;
    case "D-": thirdGrade = .67;
        break;
    case "F": thirdGrade = 0.0;
        break;
    }
    switch (fourthClass){
    case "A+": fourthGrade = 4.33;
        break;
    case "A": fourthGrade = 4.00;
        break;
    case "A-": fourthGrade = 3.67;
        break;
    case "B+": fourthGrade = 3.33;
        break;
    case "B": fourthGrade = 3.00;
        break;
    case "B-": fourthGrade = 2.67;
        break;
    case "C+": fourthGrade = 2.33;
        break;
    case "C": fourthGrade = 2.00;
        break;
    case "C-": fourthGrade = 1.67;
        break;
    case "D+": fourthGrade = 1.33;
        break;
    case "D": fourthGrade = 1.00;
        break;
    case "D-": fourthGrade = .67;
        break;
    case "F": fourthGrade = 0.0;
        break;
    }
    switch (fifthClass){
    case "A+": fifthGrade = 4.33;
        break;
    case "A": fifthGrade = 4.00;
        break;
    case "A-": fifthGrade = 3.67;
        break;
    case "B+": fifthGrade = 3.33;
        break;
    case "B": fifthGrade = 3.00;
        break;
    case "B-": fifthGrade = 2.67;
        break;
    case "C+": fifthGrade = 2.33;
        break;
    case "C": fifthGrade = 2.00;
        break;
    case "C-": fifthGrade = 1.67;
        break;
    case "D+": fifthGrade = 1.33;
        break;
    case "D": fifthGrade = 1.00;
        break;
    case "D-": fifthGrade = .67;
        break;
    case "F": fifthGrade = 0.0;
        break;
    }

    double total = firstGrade + secondGrade + thirdGrade + fourthGrade + fifthGrade;  
    double GPA = total / 5;
    System.out.println("Your GPA is: " + GPA);
}

}

}

7 个解决方案

#1


2  

Use a method like double getGrade(String) as follows

使用类似于double getGrade(String)这样的方法。

double firstGrade = getGrade(firstClass);
double secondGrade = getGrade(secondClass);
double thirdGrade = getGrade(thirdClass);
double fourthGrade = getGrade(fourthClass);
double fifthGrade = getGrade(fifthClass);

// Use your switch statement.... no break(s) because we return.
public static double getGrade(String grade) {
  switch (grade){
  case "A+": return 4.33;
  case "A": return 4.00;
  case "A-": return 3.67;
  case "B+": return 3.33;
  case "B": return 3.00;
  case "B-": return 2.67;
  case "C+": return 2.33;
  case "C": return 2.00;
  case "C-": return 1.67;
  case "D+": return 1.33;
  case "D": return 1.00;
  case "D-": return .67;
  }
  // F
  return 0.0;
}

#2


1  

You could easily create an Enum to represent those grade and put the value of the grade as field within the enum.

您可以轻松地创建一个Enum来表示这些级别,并将级别的值放在Enum中作为字段。

#3


1  

Instead of having firstGrade, secondgrade, etc., use an array or List:

使用数组或列表,而不是使用firstGrade、secondgrade等等。

double[] grades = new double[5]; // firstGrade will be grades[0], and so on.

For the letter grades, I suggest using enums, with the valueOf() method.

对于字母等级,我建议使用enums,使用valueOf()方法。

#4


1  

This method removes all switches, and only uses two if statements:

此方法删除所有开关,仅使用两个if语句:

public static double getGrade(String grade) {
  double retVal = 0.0;
  char letter = grade.getCharAt(0); //Get the letter grade

  //Compute the base grade--some of these casts may not be needed 
  //(I'm not figuring it out right now)
  retVal = Math.max((int)'A' - (int)letter + 4, 0.0);

  if (grade.length() == 1) return retVal;

  //Alter the grade based on the postfix
  char pm = grade.getCharAt(1); //Get the plus/minus

  if (pm == '+') retVal += 0.33;
  else           retVal -= 0.33;

  return retVal;
}

Then, use the array approach mentioned in "Chthonic Project"'s answer.

然后,使用“Chthonic Project”中提到的数组方法。

#5


0  

You only need one large switch statement.

你只需要一个大开关。

Instead of having firstClass/firstGrade/secondClass/secondGrade, just have two arrays, class[] and grade[]. Then you can do something like:

没有firstClass/firstGrade/secondClass/secondGrade,只有两个数组,class[]和grade[]。然后你可以这样做:

for(int i = 0; i < 5; i++){
    switch(class[i]){
         case "A+" : grade[i] = 4.33;
    }
 }

#6


0  

If you encapsulate some of the similar tasks to separate methods, it should make your code a little cleaner. try this.Hope this helps

如果您将一些类似的任务封装到不同的方法中,它应该会使您的代码更加简洁。试试这个。希望这有助于

public static void main(String[] args) {
    System.out
            .println("Welcome to the GPA calculator! Please enter your GPA into the popup window to find your GPA.");

    String firstClassInput = JOptionPane
            .showInputDialog(null,
                    "Please enter your grade for your first class: (A+, A, A-, B+, etc.)");
    String firstClass = firstClassInput.toUpperCase();
    String secondClassInput = JOptionPane
            .showInputDialog(null,
                    "Please enter your grade for your second class: (A+, A, A-, B+, etc.)");
    String secondClass = secondClassInput.toUpperCase();
    String thirdClassInput = JOptionPane
            .showInputDialog(null,
                    "Please enter your grade for your third class: (A+, A, A-, B+, etc.)");
    String thirdClass = thirdClassInput.toUpperCase();
    String fourthClassInput = JOptionPane
            .showInputDialog(null,
                    "Please enter your grade for your fourth class: (A+, A, A-, B+, etc.)");
    String fourthClass = fourthClassInput.toUpperCase();
    String fifthClassInput = JOptionPane
            .showInputDialog(null,
                    "Please enter your grade for your fifth class: (A+, A, A-, B+, etc.)");
    String fifthClass = fifthClassInput.toUpperCase();

    List<String> listOfGrades = new ArrayList<String>();
    listOfGrades.add(firstClass);
    listOfGrades.add(secondClass);
    listOfGrades.add(thirdClass);
    listOfGrades.add(fourthClass);
    listOfGrades.add(fifthClass);

    double GPA = getGPA( listOfGrades );
    System.out.println("Your GPA is: " + GPA);
}


/**
 * Used to calculate GPA from list of supplied grades
 * 
 * @param listOfGrades as list of grades to compute GPA
 * @return GPA as double
 */
public static double getGPA(List<String> listOfGrades){
    double total = 0.0;
    double GPA = 0.0;

    for(String aGrade: listOfGrades){
         total += getGrade( aGrade );

    }
    GPA = total / listOfGrades.size();
    System.out.println("Total "+total+" amount of grades: "+listOfGrades.size());
    return GPA;
}

/**
 * Get value of grade as a double type
 * 
 * @param stringGrade Grade
 * @return value of grade as 
 */
public static double getGrade(String stringGrade ){

    double grade = 0.0;
    switch (stringGrade) {
    case "A+":
        grade = 4.33;
        break;
    case "A":
        grade = 4.00;
        break;
    case "A-":
        grade = 3.67;
        break;
    case "B+":
        grade = 3.33;
        break;
    case "B":
        grade = 3.00;
        break;
    case "B-":
        grade = 2.67;
        break;
    case "C+":
        grade = 2.33;
        break;
    case "C":
        grade = 2.00;
        break;
    case "C-":
        grade = 1.67;
        break;
    case "D+":
        grade = 1.33;
        break;
    case "D":
        grade = 1.00;
        break;
    case "D-":
        grade = .67;
        break;
    case "F":
        grade = 0.0;
        break;
    }
    System.out.println("stringGrade: "+stringGrade+"="+grade);
    return grade;
}

#7


0  

I would recommend using either a Enum or a Map, mostly since there are the most human readable alternatives and it also gives you a good opportunity to decouple the data from the UI/Logic layer.

我建议使用Enum或Map,主要是因为有最适合人类阅读的替代方案,而且它还提供了一个很好的机会,可以将数据与UI/逻辑层分离。

Example Enum:

枚举例子:

public enum Grades {
    APLUS("A+", 4.33),
    A("A",4.00);

    private String label;
    private double value;
    private Grades(String label,double value){
        this.label = label;
        this.value = value;
    }

    public double getValue() {
        return value;
    }

    public static Grades getByLabel(String label){
        for(Grades grades : values()){
            if(grades.label.equals(label)){
                return grades;
            }
        }
        throw new IllegalArgumentException("Incorrect Label");
    }

}

Later used in your code with Grades.getByLabel(firstGrade).getValue(); Enum is very good if you plan on adding any extra data that is connected to each grade. Some other kind of measurement or similar, then there is no need for several arrays, lists or similar.

稍后在您的代码中使用。getbylabel (firstGrade).getValue();如果您计划添加与每个级别相连的额外数据,那么Enum是非常好的。一些其他类型的测量或类似的,然后不需要几个数组,列表或类似的。

Example Map (in a separate class):

示例映射(在单独的类中):

public class GradeValues {
private static Map<String,Double> gradeValues = new HashMap<String, Double>();
static{
    gradeValues.put("A+", 4.33);
    gradeValues.put("A", 4.00);
}

public static double getGradeValue(String grade){
    return gradeValues.get(grade);
}

}

}

Later used in your code with:

稍后在您的代码中使用:

GradeValues.getGradeValue(firstGrade);

#1


2  

Use a method like double getGrade(String) as follows

使用类似于double getGrade(String)这样的方法。

double firstGrade = getGrade(firstClass);
double secondGrade = getGrade(secondClass);
double thirdGrade = getGrade(thirdClass);
double fourthGrade = getGrade(fourthClass);
double fifthGrade = getGrade(fifthClass);

// Use your switch statement.... no break(s) because we return.
public static double getGrade(String grade) {
  switch (grade){
  case "A+": return 4.33;
  case "A": return 4.00;
  case "A-": return 3.67;
  case "B+": return 3.33;
  case "B": return 3.00;
  case "B-": return 2.67;
  case "C+": return 2.33;
  case "C": return 2.00;
  case "C-": return 1.67;
  case "D+": return 1.33;
  case "D": return 1.00;
  case "D-": return .67;
  }
  // F
  return 0.0;
}

#2


1  

You could easily create an Enum to represent those grade and put the value of the grade as field within the enum.

您可以轻松地创建一个Enum来表示这些级别,并将级别的值放在Enum中作为字段。

#3


1  

Instead of having firstGrade, secondgrade, etc., use an array or List:

使用数组或列表,而不是使用firstGrade、secondgrade等等。

double[] grades = new double[5]; // firstGrade will be grades[0], and so on.

For the letter grades, I suggest using enums, with the valueOf() method.

对于字母等级,我建议使用enums,使用valueOf()方法。

#4


1  

This method removes all switches, and only uses two if statements:

此方法删除所有开关,仅使用两个if语句:

public static double getGrade(String grade) {
  double retVal = 0.0;
  char letter = grade.getCharAt(0); //Get the letter grade

  //Compute the base grade--some of these casts may not be needed 
  //(I'm not figuring it out right now)
  retVal = Math.max((int)'A' - (int)letter + 4, 0.0);

  if (grade.length() == 1) return retVal;

  //Alter the grade based on the postfix
  char pm = grade.getCharAt(1); //Get the plus/minus

  if (pm == '+') retVal += 0.33;
  else           retVal -= 0.33;

  return retVal;
}

Then, use the array approach mentioned in "Chthonic Project"'s answer.

然后,使用“Chthonic Project”中提到的数组方法。

#5


0  

You only need one large switch statement.

你只需要一个大开关。

Instead of having firstClass/firstGrade/secondClass/secondGrade, just have two arrays, class[] and grade[]. Then you can do something like:

没有firstClass/firstGrade/secondClass/secondGrade,只有两个数组,class[]和grade[]。然后你可以这样做:

for(int i = 0; i < 5; i++){
    switch(class[i]){
         case "A+" : grade[i] = 4.33;
    }
 }

#6


0  

If you encapsulate some of the similar tasks to separate methods, it should make your code a little cleaner. try this.Hope this helps

如果您将一些类似的任务封装到不同的方法中,它应该会使您的代码更加简洁。试试这个。希望这有助于

public static void main(String[] args) {
    System.out
            .println("Welcome to the GPA calculator! Please enter your GPA into the popup window to find your GPA.");

    String firstClassInput = JOptionPane
            .showInputDialog(null,
                    "Please enter your grade for your first class: (A+, A, A-, B+, etc.)");
    String firstClass = firstClassInput.toUpperCase();
    String secondClassInput = JOptionPane
            .showInputDialog(null,
                    "Please enter your grade for your second class: (A+, A, A-, B+, etc.)");
    String secondClass = secondClassInput.toUpperCase();
    String thirdClassInput = JOptionPane
            .showInputDialog(null,
                    "Please enter your grade for your third class: (A+, A, A-, B+, etc.)");
    String thirdClass = thirdClassInput.toUpperCase();
    String fourthClassInput = JOptionPane
            .showInputDialog(null,
                    "Please enter your grade for your fourth class: (A+, A, A-, B+, etc.)");
    String fourthClass = fourthClassInput.toUpperCase();
    String fifthClassInput = JOptionPane
            .showInputDialog(null,
                    "Please enter your grade for your fifth class: (A+, A, A-, B+, etc.)");
    String fifthClass = fifthClassInput.toUpperCase();

    List<String> listOfGrades = new ArrayList<String>();
    listOfGrades.add(firstClass);
    listOfGrades.add(secondClass);
    listOfGrades.add(thirdClass);
    listOfGrades.add(fourthClass);
    listOfGrades.add(fifthClass);

    double GPA = getGPA( listOfGrades );
    System.out.println("Your GPA is: " + GPA);
}


/**
 * Used to calculate GPA from list of supplied grades
 * 
 * @param listOfGrades as list of grades to compute GPA
 * @return GPA as double
 */
public static double getGPA(List<String> listOfGrades){
    double total = 0.0;
    double GPA = 0.0;

    for(String aGrade: listOfGrades){
         total += getGrade( aGrade );

    }
    GPA = total / listOfGrades.size();
    System.out.println("Total "+total+" amount of grades: "+listOfGrades.size());
    return GPA;
}

/**
 * Get value of grade as a double type
 * 
 * @param stringGrade Grade
 * @return value of grade as 
 */
public static double getGrade(String stringGrade ){

    double grade = 0.0;
    switch (stringGrade) {
    case "A+":
        grade = 4.33;
        break;
    case "A":
        grade = 4.00;
        break;
    case "A-":
        grade = 3.67;
        break;
    case "B+":
        grade = 3.33;
        break;
    case "B":
        grade = 3.00;
        break;
    case "B-":
        grade = 2.67;
        break;
    case "C+":
        grade = 2.33;
        break;
    case "C":
        grade = 2.00;
        break;
    case "C-":
        grade = 1.67;
        break;
    case "D+":
        grade = 1.33;
        break;
    case "D":
        grade = 1.00;
        break;
    case "D-":
        grade = .67;
        break;
    case "F":
        grade = 0.0;
        break;
    }
    System.out.println("stringGrade: "+stringGrade+"="+grade);
    return grade;
}

#7


0  

I would recommend using either a Enum or a Map, mostly since there are the most human readable alternatives and it also gives you a good opportunity to decouple the data from the UI/Logic layer.

我建议使用Enum或Map,主要是因为有最适合人类阅读的替代方案,而且它还提供了一个很好的机会,可以将数据与UI/逻辑层分离。

Example Enum:

枚举例子:

public enum Grades {
    APLUS("A+", 4.33),
    A("A",4.00);

    private String label;
    private double value;
    private Grades(String label,double value){
        this.label = label;
        this.value = value;
    }

    public double getValue() {
        return value;
    }

    public static Grades getByLabel(String label){
        for(Grades grades : values()){
            if(grades.label.equals(label)){
                return grades;
            }
        }
        throw new IllegalArgumentException("Incorrect Label");
    }

}

Later used in your code with Grades.getByLabel(firstGrade).getValue(); Enum is very good if you plan on adding any extra data that is connected to each grade. Some other kind of measurement or similar, then there is no need for several arrays, lists or similar.

稍后在您的代码中使用。getbylabel (firstGrade).getValue();如果您计划添加与每个级别相连的额外数据,那么Enum是非常好的。一些其他类型的测量或类似的,然后不需要几个数组,列表或类似的。

Example Map (in a separate class):

示例映射(在单独的类中):

public class GradeValues {
private static Map<String,Double> gradeValues = new HashMap<String, Double>();
static{
    gradeValues.put("A+", 4.33);
    gradeValues.put("A", 4.00);
}

public static double getGradeValue(String grade){
    return gradeValues.get(grade);
}

}

}

Later used in your code with:

稍后在您的代码中使用:

GradeValues.getGradeValue(firstGrade);