java - 可能有多个答案的冗余 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
解决方案
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
仍然不是最好的,有封装,变量命名和其他一些问题,但很好地涵盖了这个问题。
推荐阅读
- node.js - 从我站点主域上的 URL 提供 AWS S3 图像
- javascript - 如何使用单选按钮选择单个和多个复选框
- docker - ELK Docker -- Logstash 无法正常工作
- javascript - 鼠标悬停时在棋盘上突出显示一个正方形
- python - 正则表达式在一组数字中查找最后两个位置
- typescript - 如何找出库回调的打字稿签名?
- php - 将 Mysql 回显到一个表中 - 表示和 DOM
- r - 如何在 R 中为函数参数添加选项?也就是说,当用户点击选项卡时,他们会看到参数可以采用的所有可能值
- nginx - laravel valet-linux 重定向错误
- css - 如何用emotionJS正确覆盖现有的className