Java-Day-5(数组 + 排序 + 查找 + 二维数组)
Java-Day-5
数组
可以存放多个同一类型的数据,属于引用类型
-
动态初始化
- 语法:数据类型 数组名[] = new 数据类型[大小]
- 例:int[] a = new int[5]
- 或:double a[] = new double[n]
- 使用 ( 引用/访问/获取 ) 时,初始下标 ( 索引 ) 是从 0 开始,第一个数 = a[0]
- 获取长度:数组名.length
- 也可以先定义,然后再于new的时候再开辟空间
- 语法:数据类型 数组名[] = new 数据类型[大小]
-
静态初始化
- 语法:数据类型 数组名[] =
-
注意事项:
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型,但不能混用
- 数组创建后没有赋值的话,有默认值:
- int,short,byte,long:0
- float,double:0.0
- char:\u0000
- boolean:false
- String:null
- 数组属引用类型,数组型数据是对象 ( object )
-
数组赋值机制
-
与基本数据类型不同,已有基本数据类型进行赋值,赋值方式为拷贝 ( 值传递 )
-
数组默认情况下是引用传递 ( 地址拷贝 ),赋的值是地址,赋值方式为引用赋值
int[] arr1 = {1,2}; int[] arr2 = arr1; arr2[0] = 10; // 此时arr1变成了{10,2} // 除非arr2是独立开辟的新的数据空间(如下拓展所述)
-
-
补充暂拓展:
-
上述数组的赋值在 jvm 的内存中:
-
int[] arr1 = {1,2} ——> 栈里分配一个地址指向堆(此地址具体在堆里面)
( 在内存里面只要是分配了一个空间,必定会对应一个地址 )
-
堆里面此地址里有两个数据空间,分别放元素 1 ( arr[0] ) 和 2 ( arr[1] )
-
所以 arr2 = arr1 是把地址给了 arr2 ( 同地址指向了同一个大数据空间 )
-
所以 arr2 对某数的更改就是直接改了地址指向空间里的数
-
-
除非 arr2 独立开辟出新的数据空间:int[] arr2 = new int [arr1.length];
-
-
小练习
-
// 数组反转 int temp = 0; int len = arr.length; // 前后对应的数需要交换次数:len/2 for(int i = 0; i < len / 2; i++){ temp = arr[i]; //前面数的下标对应的后面的下标:len-1-i arr[i] = arr[len - 1 - i]; arr[len - 1 - i] = temp; } // 或者新建一个独立数组逆向赋值拷贝 //若加上arr = arr2;此时arr原来数据空间就没有变量引用,会被jvm当作垃圾销毁
-
-
实现动态的给数组添加元素效果,实现对数组扩容
-
原始数组 arr 扩容
int[] arr ={1,2,3}; int[] arrNew = new int[arr.length + 1]; // 新数组赋值后:arr = arrNew; // 或用 do-while 通过用户y/n来判断是否继续往数组里添加数,y创新数组,n则break(后期链表更加高效)
-
排序
将多个数据,依照指定的顺序进行排列的过程
-
排序分类
- 内部排序:将需要处理的数据都加载到内部存储器中进行排序。包括交换式排序法、选择式排序法、插入式排序法
- 外部排序:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。包括合并排序法、直接合并排序法。
-
冒泡排序:从第一个元素开始依次比较相邻元素的值,将大的值逐渐从前移向后,n个元素进行n-1轮排序,每轮确定一个未排好的最大值并固定于后面
-
例:int[] a = {3, 5, 1, 8, 2};
int[] a = {3, 5, 1, 8, 2}; int len = a.length; int temp = 0; for (int i = 0; i < len - 1; i++){ for (int j = 0; j < len - 1 - i; j++){ if(a[j] > a[j + 1]){ temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } for (int i = 0; i < len; i++){ System.out.print(a[i] + "\t"); }
-
查找
- 顺序查找
- index 定下标,遍历,xx.equals(a[i]) 查找
- 二分查找 ( 算法的时候再涉及二分法 )
二维数组
-
动态初始化
-
基本语法定义:
-
类型[] [] 数组名 = new 类型[ 几个一维 ] [ 一维里面几个数据元素 ]
-
类型 数组名[] [] = new 类型[] []
-
类型[] 数组名[] = new 类型[] []
int[][] arr = new int[2][3]; // 遍历二维数组每个元素, // arr.length 元素为 2 (元素 = 一维数组) for(int i = 0; i < arr.length; i++){ //j分别<每一个一维数组的 i 的长度(arr[i].length) for(int j = 0; j < arr[i].length; j++){ System.out.print(arr[i][j] + " "); } System.out.println(); } // 访问第i个一维数组的第j个值: arr[i-1][j-1]
-
-
二维也可以先定义,再于new时再开辟空间
int[][] arr; arr = new int[2][3];
-
二维中每个一维的所含元素个数可以不一样,称为列数不等的二维数组,需要先定下有几个一维的,再于循环中定义每个一维的个数
//在堆中开辟了三个一维的地址,但每个一维数组没开数据空间 // 1. int[][] arr = new int[3][]; for(..; i < arr.length; ..){ //new : 根据已给地址在堆中给每个一维数组开辟要存放 //元素的空间, 否则 arr[i] 为 null,没法放元素数据 // 2. arr[i] = new int[据题意所得每个一维所含多少数]; for(..; ..; ..){ ......; } }
-
-
静态初始化
-
例 :
int[][] arr = { {1,1,1}, {2,2,2} }; // 也可以: 但不能去掉 100 外的大括号 int[][] arr = { {1,1}, {2,2,2}, {100} };
-
-
上述第一个二维数组 arr 在 jvm 的内存中:
- 仍然是二维 arr 在栈中指向一个地址,在堆中的地址
- 此堆内的地址空间含两个小空间,不存数,而是分别存有两个地址,一维的地址,仍然指向堆 ( 真正存放数据的地方 )
- 每个一维的地址指向空间都在堆中开了三个小空间,都分别存放各个一维里的三个数
-
小练习
-
//杨辉三角 //1 1.行数等于元素个数 //11 2.从第三行开始,除了第一个和最后一个元素 //121 其他的值都是:本列上一行与上一行的前一列的和 //1331 arr[i][j] = arr[i-1][j] + arr[i-1][j-1] //14641 //... int[][] yanghui = new int[5][]; for (int i = 0; i < yanghui.length; i++){ // 给每个一维数组开空间 yanghui[i] = new int[i + 1]; // 给每个一维数组赋值 for(int j = 0; j < yanghui[i].length; j++){ // 位置不是第一个也不是第二个 if(j == 0 || j == yanghui[i].length - 1){ yanghui[i][j] = 1; }else{ yanghui[i][j] = yanghui[i-1][j] + yanghui[i-1][j-1]; } } } for (int i = 0; i < yanghui.length; i++){ for (int j = 0; j < yanghui[i].length; j++){ System.out.print(yanghui[i][j] + "\t"); } System.out.println(); // 换行 } // 升序数组里添一新数,可以先定义index找到插入下标,然后break,再通过判断index是否改变,新建数组决定新数插入位置 for(int i = 0, j = 0; i < arrNew.length; i++){ if(i != index){ arrNew[i] = arr[j]; j++; // i为新数组下标,j为旧数组下标无需再加for循环 }else{ arrNew[i] = insertNum; } } arr = arrNew; // 原数组销毁
-
易错
int[] x, y[]; //声明的是一个一维x,一个二维y y[0][0] = x; //报错,int[] 无法赋值给 int y[0] = x; //正确,int[] ——> int[] y[0][0] = x[0]; //正确,int ——> int //静动结合的定义 String strs[] = new String[]{"a","b"}; //正确 String[] strs = new String[2]{"a","b"}; //错误,既然已给具体数据,只[]就可以,会被识别,不要画蛇添足
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?