软件综合实践的第一次理解做业java
方法1,2参考连接 https://blog.csdn.net/Frank_Jay/article/details/52900089编程
方法3参考连接 https://blog.csdn.net/q982151756/article/details/80647663小程序
//简易计算器小程序设计模式
阅读过程:数组
1. 网上看到一个简单的小程序,是关于输入数字和加减乘除符号,能够运算结果的安全
(阅读后理解搜索的在代码后注释着)app
1 //方法1: 2 3 package jsj; 4 5 import java.util.Scanner; 6 7 /* 8 9 * 《大话设计模式》中的计算器实现代码 10 * https://blog.csdn.net/Frank_Jay/article/details/52900089 11 12 * */ 13 14 public class Operation { //Operation 类 15 16 public static double GetResult(double numA, double numB, String opr) {//3个参数 17 18 double result = 0d;//数值后面的d,表示是double类型数,好比 double b = 3.2d 19 20 switch (opr) { //opr表示符号的选择 21 22 case "+": 23 24 result = numA + numB; 25 26 break; 27 28 case "-": 29 30 result = numA - numB; 31 32 break; 33 34 case "*": 35 36 result = numA * numB; 37 38 break; 39 40 case "/": 41 42 result = numA / numB; 43 44 break; 45 46 } 47 48 return result; 49 50 } 51 52 53 54 public static void main(String[] args) { 55 56 System.out.println("请输入数字A:"); //友好交互提示 57 58 Scanner scan = new Scanner(System.in); 59 // 从键盘接收数据 60 61 String strNumA = scan.nextLine(); // next方式接收字符串 62 //nextLine()方法返回的是Enter键以前没有被读取的全部字符,它是能够获得带空格的字符串的 63 //next()方法在读取内容时,会过滤掉有效字符前面的无效字符, 64 //对输入有效字符以前遇到的空格键、Tab键或Enter键等结束符,next()方法会自动将其过滤掉 65 // 判断是否还有输入 66 System.out.println("请输入运算符号(+、-、*、/):"); 67 68 String strOpr = scan.nextLine(); 69 70 System.out.println("请输入数字B"); 71 72 String strNumB = scan.nextLine(); 73 74 String strResult = ""; 75 76 double Result = GetResult(Double.parseDouble(strNumA), Double.parseDouble(strNumB), strOpr); 77 //数字类型的String字符串转换为浮点数一般采用parseDouble()和valueOf()方法 78 /* 79 Double.parseDouble(java.lang.String)的参数只能是String, 80 若是参数改成double类型提示“The method parseDouble(String) in the type Double is not applicable for the arguments (double)”错误。 81 Double.valueOf()的参数类型能够是浮点型或者是字符串都可。 82 */ 83 84 strResult = String.valueOf(Result); 85 86 System.out.println("结果为"+strResult); 87 88 } 89 90 91 92 }
运行结果:ide
请输入数字A:函数
11工具
请输入运算符号(+、-、*、/):
*
请输入数字B
8
结果为88.0
2.阅读过程2:以为这样的输入太麻烦了,能不能直接输入出结果呢?改进一下,不是单独输入,而是一块儿输入,直接出结果。
1 //方法2 2 3 package jsj; 4 5 6 import java.util.Scanner; 7 //java.util.Scanner 是 Java5 的新特征,咱们能够经过 Scanner 类来获取用户的输入 8 9 public class Calculator { 10 11 public static void main(String[] args) { 12 13 System.out.println("-----------------------------------"); 14 15 System.out.println("请输入一个算术表达式,如:45*23"); 16 17 Scanner in = new Scanner(System.in);// 从键盘接收数据 18 19 String str = in.nextLine();// nextline方式接收字符串 20 21 StringBuffer buffer = new StringBuffer(); 22 /*当对字符串进行修改的时候,须要使用 StringBuffer 和 StringBuilder 类。 23 和 String 类不一样的是,StringBuffer 和 StringBuilder 类的对象可以被屡次的修改,而且不产生新的未使用对象。 24 StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不一样在于 StringBuilder 的方法不是线程安全的(不能同步访问)。 25 因为 StringBuilder 相较于 StringBuffer 有速度优点,因此多数状况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的状况下,则必须使用 StringBuffer 类。 */ 26 27 StringBuffer buffer1 = new StringBuffer(); 28 29 char t = ' ';//默认初始化符号位,即“+-*/” 30 31 for (int i = 0; i < str.length(); i++) { 32 33 if (str.charAt(i) == '+' || str.charAt(i) == '-' 34 35 || str.charAt(i) == '*' || str.charAt(i) == '/') { 36 37 t = str.charAt(i);//把符号位赋值给t 38 //charAt()功能相似于数组,能够把字符串看做是char类型的数组,它是把字符串拆分获取其中的某个字符;返回指定位置的字符。 39 // charAt(i),i为int类型,i从0开始。 40 41 42 for (int j = i + 1; j < str.length(); j++) { 43 44 buffer1.append(str.charAt(j)); 45 //append() 方法在被选元素的结尾(仍然在内部)插入指定内容。 46 /*Stringbuffer 有append()方法 47 Stringbuffer实际上是动态字符串数组 48 /*Stringbuffer 有append()方法 49 append()是往动态字符串数组添加,跟“xxxx”+“yyyy”至关那个‘+’号 50 /*Stringbuffer 有append()方法 51 跟String不一样的是Stringbuffer是放一块儿的 52 String1+String2 和Stringbuffer1.append("yyyy")虽然打印效果同样,但在内存中表示却不同 53 String1+String2 存在于不一样的两个地址内存 54 Stringbuffer1.append(Stringbuffer2)放在一块儿 */ 55 56 } 57 58 break; 59 60 } else { 61 62 buffer.append(str.charAt(i)); 63 64 } 65 66 } 67 68 String c = buffer.toString();//将buffer对象转换成指定的字符编码的字符串。 69 /*好比: 70 StringBuffer sb = new StringBuffer("abcd") ; 71 sb.append("efg") ; 72 String str = sb.toString() ; 73 System.out.println(str) ; // out : "abcdefg" 74 75 使用StringBuffer的toString()方法,能够将StringBuffer转换成String */ 76 77 String d = buffer1.toString(); 78 79 double a = Double.parseDouble(c); 80 81 double b = Double.parseDouble(d); 82 /* 83 Double.parseDouble方法是把数字类型的字符串,转换成double类型 84 Double.valueOf方法是把数字类型的字符串,转换成Double类型 85 好比:字符 0.94 86 采用 valueOf 获得的结果是 0.9400000000000001 87 而采用 parseDouble 获得的结果是 0.94*/ 88 89 double sum = 0; 90 91 if (t == '+') { 92 93 sum = a + b; 94 95 } 96 97 if (t == '-') { 98 99 sum = a - b; 100 101 } 102 103 if (t == '*') { 104 105 sum = a * b; 106 107 } 108 109 if (t == '/') { 110 111 sum = a / b; 112 113 } 114 115 System.out.println("程序运算..."); 116 117 System.out.println(c+t+d+"="+sum); 118 119 System.out.print("-----------------------------------"); 120 121 } 122 123 }
运行结果:
-----------------------------------
请输入一个算术表达式,如:45*23
11*8
程序运算...
11*8=88.0
-----------------------------------
心得:
方法二是方法1的改进,更加符合人的逻辑思惟,相比于方法1更加快捷方便。
理解用户需求:一个快捷的运算输入(方法二),而不是一个个的拆分输入(方法1),那么想要更好地扩展使用,能够用有界面结构的计算机小程序。
3.阅读过程3:
仍是太麻烦了,能不能呈界面化,更加简单些,不要是数据化,这样会更加清晰!
1 //方法3: 2 3 package jsj; 4 5 import javax.swing.*; 6 import java.awt.*; 7 import java.awt.event.ActionEvent; 8 import java.awt.event.ActionListener; 9 import java.util.Stack; 10 11 class MyException extends Exception{ 12 public MyException() { 13 super(); 14 } 15 public MyException(String message) { 16 super(message); 17 } 18 } 19 20 public class MyCalculator extends JFrame{ 21 /* 22 * 23 */ 24 25 private JTextField textField; //输入文本框 26 private String input; //结果 27 private String operator; //操做符 28 29 public MyCalculator() { 30 input = ""; 31 operator = ""; 32 33 JPanel panel = new JPanel(); 34 textField = new JTextField(30); 35 textField.setEditable(false); //文本框禁止编辑 36 textField.setHorizontalAlignment(JTextField.LEFT); 37 //textField.setBounds(100, 100, 20, 20); //在容器布局为空状况下生效 38 textField.setPreferredSize(new Dimension(200,30));//设置该组件的初始大小 39 40 //将textField加入本JFrame中,布局为边界布局,位置为north 41 this.add(textField, BorderLayout.NORTH); 42 43 String[] name= {"7","8","9","+","4","5","6","-","1","2","3","*","0","C","=","/"}; 44 45 //将这个panel的布局设置为网格布局,有四行四列,行间距和列间距为1 46 panel.setLayout(new GridLayout(4,4,1,1)); 47 48 for(int i=0;i<name.length;i++) { 49 50 JButton button = new JButton(name[i]); 51 52 //设置按钮的时间监听 53 button.addActionListener(new MyActionListener()); 54 //将按钮加入到panel中 55 panel.add(button); 56 } 57 //将panel加入到本JFrame中,布局为边界布局,位置为centre 58 this.add(panel,BorderLayout.CENTER); 59 } 60 61 class MyActionListener implements ActionListener{ //内部类实现按钮响应 62 63 @Override 64 public void actionPerformed(ActionEvent e) { 65 int cnt=0; 66 String actionCommand = e.getActionCommand(); //获取按钮上的字符串 67 if(actionCommand.equals("+") || actionCommand.equals("-") || actionCommand.equals("*") 68 || actionCommand.equals("/")) { 69 input += " " + actionCommand + " "; 70 } 71 else if(actionCommand.equals("C")) { //清除输入 72 input = ""; 73 } 74 else if(actionCommand.equals("=")) { //按下等号 75 try { 76 input+= "="+calculate(input); 77 } catch (MyException e1) { 78 if(e1.getMessage().equals("被除数不能为0")) 79 input = e1.getMessage(); 80 else 81 input = e1.getMessage(); 82 } 83 textField.setText(input); 84 input=""; 85 cnt = 1; 86 } 87 else 88 input += actionCommand; //按下数字 89 90 //由于若是不按“=”按钮cnt一直未0,因此能够保证显示输入的数字和操做键 91 if(cnt == 0) 92 textField.setText(input); 93 } 94 } 95 //这里须要借助栈来完成表达式的计算,首先将字符串分割成字符串数组, 96 //由中缀的定义知数组奇数位为运算符(从第0位开始),偶数位为操做数, 97 // 所以可将偶数为操做数进栈,碰见+(-)运算符,则将下一个数以正(负)的形式压人栈中, 98 // 碰见*或/运算符,则将栈顶元素出栈与数组后一元素进行计算,并将其结果从新压入栈中, 99 // 直至遍历至数组最后一个元素。 100 101 private String calculate(String input) throws MyException{ //计算函数 102 String[] comput = input.split(" "); 103 //System.out.println(input); 104 Stack<Double> stack = new Stack<>(); 105 Double m = Double.parseDouble(comput[0]); 106 stack.push(m); //第一个操做数入栈 107 108 for(int i = 1; i < comput.length; i++) { 109 if(i%2==1) { 110 if(comput[i].equals("+")) 111 stack.push(Double.parseDouble(comput[i+1])); 112 if(comput[i].equals("-")) 113 stack.push(-Double.parseDouble(comput[i+1])); 114 if(comput[i].equals("*")) { //将前一个数出栈作乘法再入栈 115 Double d = stack.peek(); //取栈顶元素 116 stack.pop(); 117 stack.push(d*Double.parseDouble(comput[i+1])); 118 } 119 if(comput[i].equals("/")) { //将前一个数出栈作乘法再入栈 120 double help = Double.parseDouble(comput[i+1]); 121 if(help == 0) 122 throw new MyException("被除数不能为0"); 123 //不会继续执行该函数 124 double d = stack.peek(); 125 stack.pop(); 126 stack.push(d/help); 127 } 128 } 129 } 130 131 double d = 0d; 132 133 while(!stack.isEmpty()) { //求和 134 d += stack.peek(); 135 stack.pop(); 136 } 137 138 String result = String.valueOf(d); 139 return result; 140 } 141 142 public static void main(String[] args) { 143 JFrame f = new MyCalculator(); 144 f.setTitle(f.getClass().getSimpleName()); 145 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 146 f.setBounds(400, 200, 500, 300); 147 f.setVisible(true); 148 } 149 }
计算器页面显示:
总结:
//我大部分的学习,搜索都放在代码注释上了,从方法一到方法二是逻辑上的改进,不用断开输入,方法二到方法三是用户界面的改进,从无界面到习惯的有界面的改进。
该界面(方法3)相比于方法1,2更加简单明了,也就是电脑中自带的计算器界面。
程序是为了方便用户使用的,Java引入图形化界面编程。
了解了一下内容:
1.JFrame 是容器类
2.AWT 是抽象窗口组件工具包,是 Java 最先的用于编写图形节目应用程序的开发包。
3.Swing 是为了解决 AWT 存在的问题而新开发的包,它以 AWT 为基础的。
复习和学习了Java的GUI图形界面设计,以及监听器,堆栈等等的综合运用。
方法1,2参考连接 https://blog.csdn.net/Frank_Jay/article/details/52900089
方法3参考连接 https://blog.csdn.net/q982151756/article/details/80647663