首页 > 解决方案 > 可能有多个答案的冗余 if 语句的问题

问题描述

我必须编写一个程序,该程序利用方法重载来计算圆柱体、球体、圆锥体和三棱柱的表面积和体积。我需要从用户那里获取输入,然后显示正确的表面积和体积。

程序应该做的一个例子是:

Input your shape’s “a” value: none
Input your shape’s “b” value: none
Input your shape’s “c” value: none
Input your shape’s “h” value: none
Input your shape’s “l” value: none
Input your shape’s “r” value: 5
Input your shape’s “s” value: none
Would you like your answer rounded?: yes
To what decimal place?: 0
---------------------------------------------------------------------
Your shape is a sphere!
It’s volume is 524 units cubed.
It’s surface area is 314 units squared.

我已经编写了程序的大部分代码,但是我现在遇到的问题是,每当我完成输入数据时,我都会收到错误消息:“线程“main”java.util.NoSuchElementException 中的异常:未找到行”。我怀疑问题出在我用来过滤用户给我的内容的 if 语句上,因为每个语句都可以多次出现相同的异常。因此,如果我想计算球体的体积,我需要的唯一输入是半径 r 的输入,而其他所有输入都没有。但是对于圆柱体,除了半径 r 和高度 h 之外,所有其他的都不是。任何帮助将非常感激。

到目前为止,这是我的代码:

import java.util.*;

class Main {

 String a = "none"; String b = "none"; String c = "none"; String h = "none"; String r = "none"; String s = "none"; String l = "none";
 String round;
 double aP; double bP; double cP; double hP; double rP; double sP; double lP;

 public static void main(String[] args) throws Exception{
   new Main();
 }//end main

 public Main() throws Exception{
   input();
   surfaceAreaPrint();
   volumePrint();

 }//end Main

 /**
  *
  */
 public void input() throws Exception{
   Scanner sc = new Scanner(System.in);
   System.out.print("");
   System.out.print("Input your shape’s “a” value: ");
   a = sc.nextLine();
   System.out.print("Input your shape’s “b” value: ");
   b = sc.nextLine();
   System.out.print("Input your shape’s “c” value: ");
   c = sc.nextLine();
   System.out.print("Input your shape’s “h” value: ");
   h = sc.nextLine();
   System.out.print("Input your shape’s “r” value: ");
   r = sc.nextLine();
   System.out.print("Input your shape’s “s” value: ");
   s = sc.nextLine();
   System.out.print("Input your shape’s “l” value: ");
   l = sc.nextLine();
   System.out.print("Would you like your answer rounded?: ");

   round = sc.nextLine();

   System.out.print("");
   System.out.print("");

   sc.close();
   parse();

 }//end input

  public void parse() throws Exception{
    System.out.println(a);
   aP = Double.parseDouble(a);
   bP = Double.parseDouble(b);
   cP = Double.parseDouble(c);
   hP = Double.parseDouble(h);
   rP = Double.parseDouble(r);
   sP = Double.parseDouble(s);
   lP = Double.parseDouble(l);

//cylinder
  if(a == "none" && b == "none" && c == "none" && s == "none" && l != "none") {
      surfaceAreaPrint();
      return;
    }

   //sphere
   else if (a.equalsIgnoreCase("none") && b.equalsIgnoreCase("none") && c.equalsIgnoreCase("none") && s.equalsIgnoreCase("none") && h.equalsIgnoreCase("none") && s.equalsIgnoreCase("none") && l.equalsIgnoreCase("none")){
surfaceAreaPrint();
return;

  }

  //cone
  else if (a.equalsIgnoreCase("none") && b.equalsIgnoreCase("none") && c.equalsIgnoreCase("none") && s.equalsIgnoreCase("none") && h.equalsIgnoreCase("none") && l.equalsIgnoreCase("none")){
     surfaceAreaPrint();
     return;
  }
  //traingular prism
  else if (r.equalsIgnoreCase("none") && s.equalsIgnoreCase("none")){
surfaceAreaPrint();
return;
   }


 }//end parse

 public void surfaceAreaPrint() throws Exception{
   Main s = new Main(); 
   System.out.println(s.surfaceArea(hP, rP));
   System.out.println(s.surfaceArea(rP));
   System.out.println(s.surfaceArea(hP, rP, sP));
   System.out.println(s.surfaceArea(aP, bP, cP, lP, hP));

 }//end surfaceAreaPrint

  public void volumePrint() throws Exception{
   Main s = new Main(); 
   System.out.println(s.surfaceArea(hP, rP));
   System.out.println(s.surfaceArea(rP));
   System.out.println(s.surfaceArea(hP, rP)); 
   System.out.println(s.surfaceArea(bP, lP, hP)); 

 }//end volumePrint

 //surface area for cylinder
 public double surfaceArea(double hP, double rP){
   return (2.0 * Math.PI * Math.pow(rP, 2.0)) + (2.0 * Math.PI * rP * hP);

 }//end surfaceArea

 //surface area for sphere
 public double surfaceArea(double rP){
   return (4.0 * Math.PI * Math.pow(rP, 2.0));

 }//end surfaceArea

 //surface area for cone
 public double surfaceArea(double hP, double rP, double sP){
   return (Math.PI * Math.pow(rP, 2.0)) + (Math.PI * rP * sP);

 }//end surfaceArea

   //surface area for traingular prism
 public double surfaceArea(double aP, double bP, double cP, double lP, double hp){
   return (bP * lP) + (aP * hP) + (bP * hP) + (cP* hP);

 }//end surfaceArea


 //volume for cylinder
 public double volume(double hP, double rP){
   return (Math.PI * Math.pow(rP, 2.0) * hP);

 }//end volume
 //volume for sphere
 public double volume(double rP){
   return ( 4.0 / 3.0 ) * Math.PI * Math.pow(rP, 3.0);

 }//end volume

 //volume for cone
 public double volume(double hP, double rP, double sP){
   return (1.0 / 3.0 ) * Math.PI * Math.pow(rP, 2.0) * hP;

 }//end volume

   //volume for traingular prism
  /**
   * calculates volume for traingular prism
   * @param times The number of times the die is to be rolled.
   * @return The results of rolling a 6-sided die.
   */
 public double volume(double aP, double bP, double cP, double lP, double hp){
   return (1.0 / 2.0 ) * bP * lP * hP;

 }//end volume

}//end Main

标签: javaif-statementexceptionoverloadingcalculator

解决方案


TL;博士

  • 在多个块中调用相同的方法if else是多余的(直到它们不返回,所以仍然可以调用所需的方法)
  • 很多时候if可以简化长条件,如果不是,最好将条件移动到附加方法boolean isAThingIWant(..params)以保持可读性
  • 不应在构造函数中调用“业务逻辑”方法
  • 在成员方法中创建相同类的新对象可能会导致不必要的递归调用
  • 使用 InputStream 关​​闭 Scanner 对象将System.in禁止将来从该流中读取(请参阅this
  • 尝试Double.parseDouble与任何不是数字的字符串一起使用会导致NumberFormatException,即使是工程符号
  • OP 示例是一个单独的问题,但在设计类时,应使用适当的封装
  • 通常的做法是使用特定语言的编码标准(请参阅
  • 这个问题的 OOP 方法是使用形状接口和实现它的附加类 - 这将允许使用继承和多态的优点

原文:
最简单的修复方法是Main s = new Main();从下面的方法中删除并使用this当前创建的对象的引用,如下所示:

    public void surfaceAreaPrint() throws Exception{
//        Main s = new Main();
        System.out.println(this.surfaceArea(hP, rP));
        System.out.println(this.surfaceArea(rP));
        System.out.println(this.surfaceArea(hP, rP, sP));
        System.out.println(this.surfaceArea(aP, bP, cP, lP, hP));

    }//end surfaceAreaPrint

    public void volumePrint() throws Exception{
//        Main s = new Main();
        System.out.println(this.surfaceArea(hP, rP));
        System.out.println(this.surfaceArea(rP));
        System.out.println(this.surfaceArea(hP, rP));
        System.out.println(this.surfaceArea(bP, lP, hP));

    }//end volumePrint

实际上,您的示例中有几个问题和代码异味。

另一件事是您仍在将字符串与方法==中的if语句进行比较parse- 使用euqals or equalsIgnoreCase.

如果您的尝试实际上是在上述方法中从用户那里获取新输入,那么您将无法关闭扫描仪,因为关闭它会System.in关闭它后面的 InputStream,因此它不再接受任何内容。我认为删除sc.close()可能会导致您遇到不同的异常和问题(例如,程序无法按您的意愿运行)。

任何那里的每个指令else if都使用相同的方法。因此整体if else if是多余的。

编辑:
刚刚检查了删除sc.close()并保持其余部分在您的示例中将导致无限获取用户输入,因为在其中创建新的 Main 对象surfaceAreaPrint并且输入是从 Main 的构造函数调用的,因此它变为递归来电。

对于重载方法的使用,您可以像这样简单地进行:

//cylinder
if(a.equalsIgnoreCase ("none") && b.equalsIg... rest of your if) {
    System.out.println(this.surfaceArea(hP, rP));
}

但请注意,当您在输入值并使用 读取它们时只需按 Enter 键sc.nextLine(),分配的值不会保持原样,none而是会变成一个空字符串,如""NumberFormatException稍后将抛出任何Double.parseDouble.

Edit2:
现在,我看到您在不使用该特定变量时要严格输入“none”,因此为避免NumerFormatException您必须在检查字符串是否不是“none”后将值解析为 double。

您可以通过更改检查是否等于“无”来简化 if 语句以检查它们是否不存在:

//for cylinder
if(!h.equalsIgnoreCase("none") && !r.equalsIgnoreCase("none") {
//....

对于实际几何对象的表面/体积的计算,您可以假设定义其大小的值应该是>=0,因此为了更简单的解析,可以使用这种方法:

public double inputParser(String s) {
    try {
        return Double.parseDouble(s);
    } catch (NumberFormatException e) {
        return -1;
    }
}
//and used instead of straight `Double.parseDouble`:
aP = inputParser(a);
bP = inputParser(b);
//which simplifies the `if` even more to:
if(hP != -1 && rP != -1) { //cylinder
    System.out.println(this.surfaceArea(hP, rP));
}

Edit3:
经过几分钟的讨论并发现了 OP 代码中的一些其他缺陷,我提出了一个解决方案:

import java.util.*;
class Main {

    String a, b, c, h, r, s, l;
    String round;
    double aP; double bP; double cP; double hP; double rP; double sP; double lP;

    public static void main(String[] args) {
        Main m = new Main();
        m.input();
        m.parse();
        m.calculate();
    }

    public void input() {
        Scanner sc = new Scanner(System.in);
        System.out.print("");
        System.out.print("Input your shape’s “a” value: ");
        a = sc.nextLine();
        System.out.print("Input your shape’s “b” value: ");
        b = sc.nextLine();
        System.out.print("Input your shape’s “c” value: ");
        c = sc.nextLine();
        System.out.print("Input your shape’s “h” value: ");
        h = sc.nextLine();
        System.out.print("Input your shape’s “r” value: ");
        r = sc.nextLine();
        System.out.print("Input your shape’s “s” value: ");
        s = sc.nextLine();
        System.out.print("Input your shape’s “l” value: ");
        l = sc.nextLine();
        System.out.print("Would you like your answer rounded?: ");

        round = sc.nextLine();
        System.out.println("");

        sc.close();
    }

    public void parse() {
        System.out.println(a);
        aP = inputParser(a);
        bP = inputParser(b);
        cP = inputParser(c);
        hP = inputParser(h);
        rP = inputParser(r);
        sP = inputParser(s);
        lP = inputParser(l);
    }

    public void calculate() {
        if(hP != -1 && rP != -1) {
            System.out.println("Cylinder");
            System.out.println(this.rounding(this.surfaceArea(hP, rP)));
            System.out.println(this.rounding(this.volume(hP, rP)));
        }
        if (rP != -1){
            System.out.println("Sphere");
            System.out.println(this.surfaceArea(rP));
            System.out.println(this.volume(rP));
        }
        if (hP != -1 && rP != -1 && sP != -1){
            System.out.println("Cone");
            System.out.println(this.surfaceArea(hP, rP, sP));
            System.out.println(this.volume(hP, rP, sP));
        }
        if (aP != -1 &&  bP != -1 &&  cP != -1 &&  lP != -1 &&  hP != -1){
            System.out.println("Triangular prism");
            System.out.println(this.surfaceArea(aP, bP, cP, lP, hP));
            System.out.println(this.volume(aP, bP, cP, lP, hP));
        }
    }
    public double rounding(double value) {
        if ("yes".equalsIgnoreCase(round)) {
            return Math.round(value);
        }
        return value;
    }
    public double inputParser(String s) {
        try {
            return Double.parseDouble(s);
        } catch (NumberFormatException e) {
            return -1;
        }
    }
    //surface area for cylinder
    public double surfaceArea(double hP, double rP){
        return (2.0 * Math.PI * Math.pow(rP, 2.0)) + (2.0 * Math.PI * rP * hP);

    }//end surfaceArea

    //surface area for sphere
    public double surfaceArea(double rP){
        return (4.0 * Math.PI * Math.pow(rP, 2.0));

    }//end surfaceArea

    //surface area for cone
    public double surfaceArea(double hP, double rP, double sP){
        return (Math.PI * Math.pow(rP, 2.0)) + (Math.PI * rP * sP);

    }//end surfaceArea

    //surface area for traingular prism
    public double surfaceArea(double aP, double bP, double cP, double lP, double hp){
        return (bP * lP) + (aP * hP) + (bP * hP) + (cP* hP);

    }//end surfaceArea


    //volume for cylinder
    public double volume(double hP, double rP){
        return (Math.PI * Math.pow(rP, 2.0) * hP);

    }//end volume
    //volume for sphere
    public double volume(double rP){
        return ( 4.0 / 3.0 ) * Math.PI * Math.pow(rP, 3.0);

    }//end volume

    //volume for cone
    public double volume(double hP, double rP, double sP){
        return (1.0 / 3.0 ) * Math.PI * Math.pow(rP, 2.0) * hP;

    }//end volume

    //volume for traingular prism
    public double volume(double aP, double bP, double cP, double lP, double hp){
        return (1.0 / 2.0 ) * bP * lP * hP;

    }//end volume

}//end Main

仍然不是最好的,有封装,变量命名和其他一些问题,但很好地涵盖了这个问题。


推荐阅读