9.21课上问题与思考
在本周的Java课上我获得了以下的思考与感受
一、懒人造就了方法
对于相同的开山一事,愚公和李冰有不同的方式去处理。愚公选择一点点去凿山,靠日积月累的努力去完成目标,李冰靠烧石头来对其进行粉碎,进而节省时间来完成目标。从愚公与李冰两人开山的不同方法可以看出,李冰的方面更加节省时间,他的方法和愚公的凿山相比更“偷懒”也更方便。这其中便蕴含了编程思维:不要按部就班的按着之前的老路子来,要善于寻找新方法来解决自己的工作量。比如说代码行数太多不方便处理,于是就有了单元文件的出现等事实,这就是我们所说的懒人造就了方法。
二、java模块实训:JDK中的MATH类
在编程过程中,我们会遇到一些数学问题,我们可以自己编写函数来实现该功能,也可以调用jdk里面的math类
如图先代码所示 这是一些math类的内容
public class math { public static void main(String[] args) { /*---------下面是三角运算---------*/ //将弧度转换角度 System.out.println("Math.toDegrees(1.57):" + Math.toDegrees(1.57)); //将角度转换为弧度 System.out.println("Math.toRadians(90):" + Math.toRadians(90)); //计算反余弦,返回的角度范围在 0.0 到 pi 之间。 System.out.println("Math.acos(0.3):" + Math.acos(1.2)); //计算反正弦;返回的角度范围在 -pi/2 到 pi/2 之间。 System.out.println("Math.asin(0.8):" + Math.asin(0.8)); //计算反正切;返回的角度范围在 -pi/2 到 pi/2 之间。 System.out.println("Math.atan(2.3):" + Math.atan(2.3)); //计算三角余弦。 System.out.println("Math.cos(1.57):" + Math.cos(1.57)); //计算值的双曲余弦。 System.out.println("Math.cosh(1.2 ):" + Math.cosh(1.2 )); //计算正弦 System.out.println("Math.sin(1.57 ):" + Math.sin(1.57 )); //计算双曲正弦 System.out.println("Math.sinh(1.2 ):" + Math.sinh(1.2 )); //计算三角正切 System.out.println("Math.tan(0.8 ):" + Math.tan(0.8 )); //计算双曲余弦 System.out.println("Math.tanh(2.1 ):" + Math.tanh(2.1 )); //将矩形坐标 (x, y) 转换成极坐标 (r, thet));,返回所得角 theta。 System.out.println("Math.atan2(0.1, 0.2):" + Math.atan2(0.1, 0.2)); /*---------下面是取整运算---------*/ //取整,返回小于目标数的最大整数。 System.out.println("Math.floor(-1.2 ):" + Math.floor(-1.2 )); //取整,返回大于目标数的最小整数。 System.out.println("Math.ceil(1.2):" + Math.ceil(1.2)); //四舍五入取整 System.out.println("Math.round(2.3 ):" + Math.round(2.3 )); /*---------下面是乘方、开方、指数运算---------*/ //计算平方根。 System.out.println("Math.sqrt(2.3 ):" + Math.sqrt(2.3 )); //计算立方根。 System.out.println("Math.cbrt(9):" + Math.cbrt(9)); //返回欧拉数 e 的n次幂。 System.out.println("Math.exp(2):" + Math.exp(2)); //返回 sqrt(x2:" +y2),没有中间溢出或下溢。 System.out.println("Math.hypot(4 , 4):" + Math.hypot(4 , 4)); // 按照 IEEE 754 标准的规定,对两个参数进行余数运算。 System.out.println("Math.IEEEremainder(5 , 2):" + Math.IEEEremainder(5 , 2)); //计算乘方 System.out.println("Math.pow(3, 2):" + Math.pow(3, 2)); //计算自然对数 System.out.println("Math.log(12):" + Math.log(12)); //计算底数为 10 的对数。 System.out.println("Math.log10(9):" + Math.log10(9)); // 回参数与 1 之和的自然对数。 System.out.println("Math.log1p(9):" + Math.log1p(9)); /*---------下面是符号相关的运算---------*/ //计算绝对值。 System.out.println("Math.abs(-4.5):" + Math.abs(-4.5)); //符号赋值,返回带有第二个浮点数符号的第一个浮点参数。 System.out.println("Math.copySign(1.2, -1.0):" + Math.copySign(1.2, -1.0)); //符号函数;如果参数为 0,则返回 0;如果参数大于 0,则返回 1.0;如果参数小于 0,则返回 -1.0。 System.out.println("Math.signum(2.3):" + Math.signum(2.3)); /*---------下面是大小相关的运算运算---------*/ //找出最大值 System.out.println("Math.max(2.3 , 4.5):" + Math.max(2.3 , 4.5)); //计算最小值 System.out.println("Math.min(1.2 , 3.4):" + Math.min(1.2 , 3.4)); //返回第一个参数和第二个参数之间与第一个参数相邻的浮点数。 System.out.println("Math.nextAfter(1.2, 1.0):" + Math.nextAfter(1.2, 1.0)); //返回比目标数略大的浮点数 System.out.println("Math.nextUp(1.2 ):" + Math.nextUp(1.2 )); //返回一个伪随机数,该值大于等于 0.0 且小于 1.0。 System.out.println("Math.random():" + Math.random()); } }
以上的函数方法都是静态方法,可以直接用类名.方法名的形式来调用
使用静态引用
只要声明了 import static java.lang.Math.* 后
以上的函数方法可以通过直接使用方法名来调用 —— System.out.print("abs(3)");
三、自定义java实例:随机数的生成
在日常编码过程中会经常遇见生成随机数的问题 通常我们都是通过调用Random()方法来实现
通过引用 import java.util.Random 直接调用Random a=new Random(); int x=a.Random(4);
或 int x=(int )(Math.random()*6); 来实现
下面是生成一组随机数的代码
源码如下
import javax.swing.JOptionPane; public class math { public static void main( String args[] ) { int value; String output = ""; for ( int i = 1; i <= 20; i++ ) { value = 1 + (int) ( Math.random() * 6 ); output += value + " "; if ( i % 5 == 0 ) output += "\n"; } JOptionPane.showMessageDialog( null, output, "20 Random Numbers from 1 to 6", JOptionPane.INFORMATION_MESSAGE ); System.exit( 0 ); } }
该代码使用了图形界面,编译结果如下
相同的数为种子生成的随机数相等
以当前时间为随机数的种子生成随机数
通过 Random r4 = new Random(System.currentTimeMillis()); 来实现将时间作为随机数种子
利用随机数来实现模拟骰子滚动的效果
四、动手动脑
编写一个一个纯随机数生成器
源码如下
package MATH; import java.util.Random; public class math{ public static void main(String []args) { Random random=new Random(); int []x=new int [1000]; x[0]=random.nextInt(1,10); for(int i=1;i<1000;i++) { int a=random.nextInt(1,2^31-1); int b=random.nextInt(1,16807); x[i]=(x[i-1]*a)%b; System.out.println(x[i]); } } }
编译结果如下
五、动手动脑 ——方法重载
// MethodOverload.java // Using overloaded methods public class MethodOverload { public static void main(String[] args) { System.out.println("The square of integer 7 is " + square(7)); System.out.println("\nThe square of double 7.5 is " + square(7.5)); } public static int square(int x) { return x * x; } public static double square(double y) { return y * y; } }
方法重载的条件为
1)方法名相同; (2)参数类型不同,参数个数不同,或者是参数类型的顺序不同。
六、递归
自己调用符合自己条件的,两个互不干扰
通过调用递归公式来一步一步实现目的
package MATH; import java.math.BigInteger; import java.util.Scanner; public class math{ /** * @param args */ public static void main(String[] args) { System.out.print("请输入N:"); Scanner scanner=new Scanner(System.in); int number=scanner.nextInt(); System.out.println(number+"!="+calculateN2(number)); } public static long calculateN(int n) { if(n==1 || n==0){ return 1; } return n*calculateN(n-1); } public static BigInteger calculateN2(int n) { if(n==1 || n==0){ return BigInteger.valueOf(1); } return BigInteger.valueOf(n).multiply(calculateN2((n-1))); } }
七、处理大数字与浮点数
计算机使用固定的数位来保存数据,对于超出自己数位的数字,计算机会采用二进制保存,因此对于大数字的计算要使用下面方法
public static BigInteger calculateN2(int n) { if(n==1 || n==0) { return BigInteger.valueOf(1); } return BigInteger.valueOf(n).multiply(calculateN2((n-1))); }
若比较浮点数的大小,也不能直接比较 因为计算机不能准确的表达出浮点数
所以要比较两者的差的绝对值是否在某个范围内来比较浮点数
if ( Math.Abs(i - j) < 1e-10 ) System.out.println("true"); else System.out.println("false");