数组
-
可以存储多个相同数据类型的容器
-
定义格式
// 1.数据类型[] 数组名 = new 数据类型[元素个数/数组长度]; //int[] arr = new int[2]; int[] arr1; // 声明 arr1 = new int[2]; // 初始化, 系统默认初始值为0 arr1[1] = 10; // 对数组元素做操作 System.out.println(arr1); //[I@16b98e56 /* [I@16b98e56 ----- 代表内存地址值 [ ----- 代表对象的类型 ([ 为数组类型) I ----- 代表数组的元素类型 (I为int类型) @ ----- 代表后面的是地址 16b98e56 ----- 哈希码值的十六进制表现形式 */ // 2.数据类型[] 数组名 = new 数据类型[]{元素值1, 元素值2, 元素值3,...}; // int []arr = new int[]{1,4,7,8,9}; // 给定了值也就确定了数组的长度 int [] arr; // 声明 arr = new int[]{1,4,5,7,9}; // 初始化 // 3. 数据类型[] 数组名 = {元素值1, 元素值2, 元素值3,...}; int[] arr2 = {1, 3, 5, 7, 9}; // 给定了值也就确定了数组的长度 int [] arr; // 声明 arr = {1,4,5,7,9}; //初始化 (error) 没有开辟内存空间无法存储元素!
-
java内存(栈+堆部分)
- 栈:存储变量(暂且),如果存储的内容使用完毕就立即清除,不会对存储的内容赋予初始值。
- 堆:存储对象,如果存储的对象不再使用要等到某个时刻让系统进行回收,会对存储的内容赋予默认初始值。
- new开辟的内存空间在堆
- 堆内存系统默认初始值 — (byte, short, int 0) (char ‘\u0000’) (long 0L) (float 0.0F) (double 0.0) (boolean false) (引用类型 null)
- 系统默认初始值优先于程序初始值执行
-
数组应用
-
遍历
// 1. 通过普通for循环输出 for(int i=0;i<arr.length;i++){ System.out.println(arr[i]); } // 2. 通过增强for循环输出 --- 迭代器 // 把每个数组元素复制一份出来进行遍历 (存储在栈区) // 不能增删原数组元素 --- 只能做遍历 //(数组的元素类型 变量名: 要去遍历的数组名) for (int i:arr){ System.out.println(i); } // 3.转成字符串 import java.util.Arrays; System.out.println(Arrays.toString(arr));
-
最值
int max = arr[0]; for(int i=1; i<arr.length; i++){ if(arr[i] > max){ max = arr[i]; } } System.out.println(max);
-
逆序
// 方法一:定义辅助数组 int[] reverArr = new int[arr.length]; for(int i=0; i<arr.length; i++){ reverArr[arr.length-1-i] = arr[i]; } // 把新数组的地址值对原数组进行覆盖 arr = reverArr; // 方法二:交换值 for(int i=0; i<arr.length/2; i++){ // 按照下标规律交换元素值 int tmp = arr[i]; arr[i] = arr[arr.length-1-i]; arr[arr.length-1-i] = tmp; }
-
查找
// 无序数组 for(int i = 0; i <length; i++){ if(target == arr[i]){ System.out.println(i); break; } } //有序数组 //二分查找 public static int binarySearch(int[] arr, int target) { int min = 0; int max = arr.length-1; while(min <= max){ int mid = (min + max)/2; if (arr[mid] == target){ return mid; } else if(arr[mid] < target){ min = mid +1; } else{ max = mid -1; } } return -1; }
-
排序
// 直接调用sort函数 import java.util.Arrays; Arrays.sort(arr); // 1.冒泡排序 public static void bubbleSort(int arr[]){ for(int i = arr.length-1; i >= 1; i--){ // arr.length-1轮交换 int flag = 0; // 标记本轮是否有交换,0表示未交换,1表示交换 for (int j = 0; j < i; j++){ if (arr[j] > arr[j+1]){ int tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp; flag = 1; // 本轮发生了交换 } } if (flag == 0){ break; // 若本轮未发生交换排序结束 } } } // 2.选择排序 public static void selectSort(int arr[]){ for (int i = 0; i < arr.length - 1; i++){ int k = i; //记录本轮最小值的下标 for (int j = i+1; j < arr.length; j++){ if (arr[j] < arr[k]){ k = j; } } if (k != i){ //交换最小值与当前无序序列的第一个关键字 int tmp = arr[i]; arr[i] = arr[k]; arr[k] = tmp; } } }
-
扩容 — 数组定义完成长度无法改变 — 扩容依赖于数组的复制
int[] arr = {2, 3, 1, 5}; // 定义新数组 int[] newArr = new int[arr.length*2]; // 把原数组的内容复制到新数组中 System.arraycopy(arr,0,arr1,0,arr.length); // arraycopy(原数组,原数组起始下标,新数组,新数组起始下标,复制的元素个数); // 用新数组的地址覆盖原数组 arr = newArr; // 一步到位版本,由上述三步实现 arr = Arrays.copyOf(arr, arr.length*2); // Arrays.copyOf(原数组, 长度)
-
-
二维数组
-
定义格式
// 1. 数据类型[][] 数组名 = new 数据类型[二维数组长度/一维数组的个数][一维数组的个数]; // int[][] arr = new int[2][3]; int[][] arr; // 声明 arr = new int [2][3]; // 初始化 System.out.println(arr); // 二维数组地址值 [[I@16b98e56 System.out.println(arr[0]); // 一维数组地址值 [I@7ef20235 System.out.println(arr[0][0]); // 第一个数组元素 // 2. 数据类型[][] 数组名 = new 数据类型[二维数组长度/一维数组的个数][]; int [][] arr = new int[3][]; // 声明三个一维数组 // 输出一维数组 System.out.println(arr[0]); // null(没有开辟内存空间) // System.out.println(arr[0][0]); // error // NullPointerException --- 空指针异常 arr[0] = new int[4]; // correct // arr[1] = {1,2,3}; // error---没有用new开辟空间 arr[1] = new int[3]; arr[2] = new int[]{4,5,6} // correct // 3.数据类型[][] 数组名 = {{1,2,...},{4,5,...},...{n1,n2,...}}; int [][] arr = {{1,2,3},{4,5},{6,7,8}};
-
-
遍历
// 1. 普通for循环 for (int i = 0; i < arr.length; i++){ for (int j = 0; j < arr[i].length; j++){ System.out.print(arr[i][j]+" "); } System.out.println(); } // 2. 增强for循环 for (int[] i: arr){ System.out.println(); for (int j:i){ System.out.print(j+" "); } }
方法
-
书写格式
修饰符 返回值类型 方法名 (参数类型 参数名, ...) { 方法体; return 返回值; } 注:java的方法不能嵌套定义
-
重载:在一个类中出现了方法名一致,参数列表不一致的方法
- 方法签名:方法的名字与参数列表(参数类型、个数、顺序)共同作用
- 调用重载方法时会根据提供的重载方法进行精确匹配
- 如果没有提供精确匹配的方法会进行相对精确匹配
- 如果提供多个相对精确的方法就无法匹配,报错
public class MethodDemo { public static void main(String[] args) { System.out.println(sum(3,2)); } // 精确匹配 // public static int sum(int m, int n){ // return m+n; // } // 相对精确匹配 // public static double sum(int m, double n){ // return m+n; // } // 提供两个相对精确的方法就无法匹配 public static double sum(double m, int n){ return m+n; } }
-
方法传值
- java中所有的方法在栈中执行
- 当实参传入的是基本类型数据,传输的是值的拷贝
- 当实参传入的是引用类型数据,传输的是地址值的拷贝
- 如果根据传输过来的地址值可以找到原堆内存并且改变元素就会影响原堆内存。
- 传输过来的地址值没有去操作原堆内存就不会影响原堆内存。
public class MethodDemo2 { public static void main(String[] args) { int[] arr = {3,1,7}; // 传输的是基本数据类型 int num = fun(arr[0]); System.out.println(num); // 4 System.out.println(arr[0]); // 3 // 传输的是引用数据类型 int num2 = fun(arr); System.out.println(num2); // 4 System.out.println(arr[0]); // 4 fun2(arr); System.out.println(arr[0]); // 4 --- 操作的是创建的新数组,不是原数组 } public static int fun(int m){ // 接受的是实参的拷贝 return ++m; } public static int fun(int[] arr){ // 接受的是地址值的拷贝 return ++arr[0]; } public static void fun2(int[] arr){ arr = new int[2]; // 新的数组地址值覆盖原数组地址值 arr[0] = 10; } }