1.函数
-
重载
// 关键字 :public,static等 // 保留字 : 关键字的预备役 var,goto // jdk11开始,还有JS里var升级为关键字: var 变量名 = 初始值 ; // 重载 / overload : 在同一个类中,允许函数重名 , 但是他们的 参数列表必须不同. // 1.参数个数不同 2. 参数类型不同 // 注意 : 1.形参的名字 2.返回值类型 这两个因素不同也不能重载 //例如System.out.println(),就使用到了重载 System.out.println(123); System.out.println("abc"); System.out.println(add(10)); byte b = 127; System.out.println(add(b)); System.out.println(add(b, 3306));//重载同样适用自动类型转换. 没有定义的函数,如果能自动类型转换,也能正常调用 } // 计算任意个数的加法 public static double add(int i){ return ++i; } public static double add(byte i){ return ++i; } public static double add(int i, int j){ return i + j;
-
递归
// recursion/递归 : 函数自己调用自己称为递归 // 前提 : 必须有结束条件并且不能递归太深 public static void main(String[] args) { // 斐波那契数列 1,1,2,3,5,8,13,21..... // 从第二项开始,每一项都等于前两项之和. n = (n-1) + (n-2) System.out.println(recursion(30)); System.out.println(recursion(5)); } static int recursion(int num){ if (num == 1 || num == 2) { return 1; } return recursion(num - 1) + recursion(num - 2); // n = (n-1) + (n-2) }
-
代码优化
// 问题-----百钱买百鸡:一只公鸡值5元钱,一只母鸡值3元钱,三只小鸡值1元钱。 现用百元买百鸡,请问各多少只鸡。 // 第一个程序,单纯的三次循环,各100次 long startTime = System.nanoTime();// 获得当前时间(纳秒) 等同于 Date中的getTime(); for (int x = 0; x <= 100; ++x) { for (int y = 0; y <= 100; ++y) { for (int z = 0; z <= 100; ++z) { if (x + y + z == 100 && 5 * x + 3 * y + z / 3 == 100 && z % 3 == 0) { System.out.println("x = " + x + " , y = " + y + " , z = " + z); } } } } long endTime = System.nanoTime();// 程序结束时间 System.out.println((endTime - startTime) + " 纳秒! "); // 第二个程序,因为公鸡不可能超过25,母鸡33,所以设定时无需100次循环 startTime = System.nanoTime(); for (int x = 0; x <= 25; ++x) { for (int y = 0; y <= 33; ++y) { for (int z = 0; z <= 100; ++z) { if (x + y + z == 100 && 5 * x + 3 * y + z / 3 == 100 && z % 3 == 0) { System.out.println("x = " + x + " , y = " + y + " , z = " + z); } } } } endTime = System.nanoTime(); System.out.println((endTime - startTime) + " 纳秒! "); // 第三个程序,小鸡必然是3只一起,因此也无需100次循环 startTime = System.nanoTime(); for (int x = 0; x <= 25; ++x) { for (int y = 0; y <= 33; ++y) { for (int z = 0; z <= 100; z += 3) { // z+=3,无需+1+1进行 if (x + y + z == 100 && 5 * x + 3 * y + z / 3 == 100) { System.out.println("x = " + x + " , y = " + y + " , z = " + z); } } } } endTime = System.nanoTime(); System.out.println((endTime - startTime) + " 纳秒! "); // 第四个程序 x + y + z == 100,因此z = 100 - x - y. 小鸡无需再循环,两个循环就可以 startTime = System.nanoTime(); for (int x = 0; x <= 25; ++x) { for (int y = 0; y <= 33; ++y) { int z = 100 - x - y; if (5 * x + 3 * y + z / 3 == 100 && z % 3 == 0) { System.out.println("x = " + x + " , y = " + y + " , z = " + z); } } } endTime = System.nanoTime(); System.out.println((endTime - startTime) + " 纳秒! "); // 第五个程序 在第四个程序的基础上,将z % 3 == 0提前. // 因为 z % 3 == 0 计算量小,&&后如果false,后面运算量较大的表达式,就不用再执行了 startTime = System.nanoTime(); for (int x = 0; x <= 25; ++x) { for (int y = 0; y <= 33; ++y) { int z = 100 - x - y; if (z % 3 == 0 && 5 * x + 3 * y + z / 3 == 100) { // 将z % 3 == 0提前 System.out.println("x = " + x + " , y = " + y + " , z = " + z); } } } endTime = System.nanoTime(); System.out.println((endTime - startTime) + " 纳秒! "); // 第六个程序 直接在开头声明x,y,z.这样第二个循环时,不用每次都对y,z 声明-赋值,只需要赋值即可,节省了一个步骤 startTime = System.nanoTime();// 单位纳秒 for (int x = 0, y, z; x <= 25; ++x) { for (y = 0; y <= 33; ++y) { z = 100 - x - y; if (z % 3 == 0 && 5 * x + 3 * y + z / 3 == 100) { System.out.println("x = " + x + " , y = " + y + " , z = " + z); } } } endTime = System.nanoTime();// 单位纳秒 System.out.println((endTime - startTime) + " 纳秒! "); /* 总结:提升程序效率基本有两点 1.考虑需求的实际情况,在逻辑层面,减少对于不可能(不必要)情况的判定.尤其是一些数学问题,考虑清楚逻辑,可以减少很多无意义运算. 2.注意Java语言本身的特性,在语言特性方面,例如程序五,程序六,减少无效操作.也可以提升效率. */
2.数组
-
初识数组
/* 数组/Array : 一组相同类型的数据的组合 声明 : 1.数据类型[] 数组名; // 开发推荐 2.数据类型 数组名[]; */ int[] arr1; // 初始化 : // 1.静态初始化 : 数据类型[] 数组名 = new 数据类型[]{具体的变量(元素),多个元素之间逗号隔开} ; arr1 = new int[]{}; // 没有元素的数组称为空数组 , 就是元素个数为 0 的数组 int[] arr2 = {1,2,3}; // 如果声明和赋值一起,可以用这种写法,不然 //arr1= {1,2,3}; 声明和赋值不一起,就不能这样写,只能用下面方式赋值: arr1 = new int[]{5,6,7}; // 数组中元素的个数 : 数组名.length System.out.println("arr1.length = " + arr1.length); System.out.println("arr2.length = " + arr2.length); // 区分元素 : 数组名[索引值] // 索引值/index : 从 0 开始 依次递增 最后一个元素的索引值 :数组名.length - 1 System.out.println(arr2[arr2.length - 1]); //数组变量本身记录的值,是数组的地址 System.out.println(arr1);// [: 数组 I : int @ : 分隔符 1b6d3586 : 十六进制地址值 // 2.动态初始化 : // new : 是在堆内存中开辟新的空间 // 动态声明 : 数据类型[] 数组名 = new 数据类型[元素个数] ; int[] arr3 = new int[5]; int[] arr4 = new int[5]; System.out.println(arr1 == arr2);// false,new会开辟新空间 System.out.println(arr3[0]); // 动态声明的数组都是有默认值的.数值是0,字符是' ',布尔是false
-
数据传递
public static void main(String[] args) { /* 调用函数时,需要注意: 1.基本数据类型之间是值传递 2.引用数据类型之间是地址值传递 不然会有意料外的值变动 */ int i = 10; int result = m1(i); System.out.println("i = " + i);// 10 int[] arr = {10, 10, 10}; m2(arr); System.out.println(arr[0]);// 11 } private static int m1(int num) { return ++num; } private static void m2(int[] array) { ++array[0]; }