Java 数组
备注:如有错误请联系。
-
1.Java数组的定义
Java 语言中提供的数组是用来存储固定大小的同类型元素。
-
2.Java数组的声明
首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
dataType[] arrayRefVar; // 首选的方法
或 dataType arrayRefVar[]; // 效果相同,但不是首选方法
实例
double[] myList; // 首选的方法
或 double myList[]; // 效果相同,但不是首选方法
-
3.数组的优势与局限
优点:1.按照索引查询元素速度快 2.能存储大量数据 3.按照索引遍历数组方便
缺点:1.根据内容查找元素速度慢2.数组的大小一经确定不能改变。3.数组只能存储一种类型的数据4. 增加、删除元素效率慢5.未封装任何方法,
所有操作都需要用户自己定义。
-
4.数组的动态化初始化
数据类型[] 数组名 = new 数据类型[数组长度];
实例
int[] arr = new int[3];
/*
* 左边:
* int:说明数组中的元素的数据类型是int类型
* []:说明这是一个数组
* arr:是数组的名称
* 右边:
* new:为数组分配内存空间
* int:说明数组中的元素的数据类型是int类型
* []:说明这是一个数组
* 3:数组的长度,其实就是数组中的元素个数
*/
拓展:静态初始化的格式
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...};
简化格式:数据类型[] 数组名 = {元素1,元素2,...};
实例:int[] arr = new int[]{1,2,3};
简化后:int[] arr = {1,2,3};
-
5.数组的存储机制
1.数组是一种引用类型。
2.数组用来存储类型相同的一组数据,一旦初始化完成,其所占的空间也确定下来了,即使清除某个元素,其所占用的空间仍然存在,
即,数组的长度不能被改变,且数组只有在分配空间后才能使用。
3.数组的初始化方式有两种,a, 动态初始化,只指定长度,后面再进行初始值的指定 int[] dynamic_initial = new int[len]; b. 静态初始化,
不指定长度,直接给出初始值,数组长度就是初始值的个数 int[] static_iniyial = new int[] {1,2,3};
4.数组的引用变量存放在栈中,其元素则存放在堆内存中。
(说明:基本数据类型、局部变量都是存放在栈内存中的,用完就消失。new创建的实例化对象及数组,
是存放在堆内存中的,用完之后靠垃圾回收机制不定期自动消除。)
5.另外,以 int 型数组为例,也可以发现,基本数据类型在堆中也会出现。
int[] array=new int[]{1,2};
由于new了一个对象,所以new int[]{1,2}这个对象时存储在堆中的,也就是说1,2这两个基本数据类型是存储在堆中
-
6.数组的遍历访问
1)数组的访问
1 public class TestArray { 2 public static void main(String[] args) { 3 // 数组大小 4 int size =3; // 定义数组 5 double[] myList = new double[size]; 6 myList[0] = 5.6; //给第一个元素赋值5.6 7 myList[1] = 4.5; 8 myList[2] = 3.3; 9 System.out.println(myList.length);//通过数组名.length可以获取数组的长度 10 System.out.println(myList[0]);//访问数组中的元素 11 } 12 }
2)数组的遍历
1 public class TestArray { 2 public static void main(String[] args) { 3 double[] myList = {1.9, 2.9, 3.4, 3.5}; // 打印所有数组元素 4 for(int i = 0; i < myList.length; i++){ 5 System.out.println(myList[i] + " "); 6 } 7 // 计算所有元素的总和 8 double total = 0; 9 for (int i = 0; i < myList.length; i++) { 10 total += myList[i]; 11 } 12 System.out.println("Total is " + total); 13 // 查找最大元素 14 double max = myList[0]; 15 for (int i = 1; i < myList.length; i++) { 16 if (myList[i] > max) max = myList[i]; 17 } 18 System.out.println("Max is " + max); 19 } 20 }
For-Each 循环
JDK 1.5 引进了一种新的循环类型,被称为 For-Each 循环或者加强型循环,它能在不使用下标的情况下遍历数组。
语法格式如下:
for(type element: array){
System.out.println(element);
}
1 public class TestArray { 2 public static void main(String[] args) { 3 double[] myList = {1.9, 2.9, 3.4, 3.5}; // 打印所有数组元素 4 for (double element: myList) { 5 System.out.println(element); 6 } 7 } 8 }
-
7.数组元素的顺序查找(数组中查找某个元素)
顺序查找的基本思想:
从表的一端开始,顺序扫描表,依次将扫描到的结点关键字和给定值(假定为a)相比较,若当前结点关键字与a相等,则查找成功;若扫描结束后,
仍未找到关键字等于a的结点,则查找失败。
1 public static void main(String[] args) { 2 int arr[]={10,50,40,90,77,12,8,88,46,99,4,30,66}; 3 System.out.println("请输入要查询的数字:"); 4 Scanner scan=new Scanner(System.in); 5 int input=scan.nextInt(); 6 SequentialSearch(arr,input); 7 8 } 9 public static void SequentialSearch(int[] arr,int input){ 10 11 for(int i=0;i<arr.length;i++){ 12 if(arr[i]==input){ 13 System.out.println(input+"的位置为:"+i); 14 break; 15 } 16 if(i==arr.length-1) 17 System.out.println("没有搜到结果!"); 18 } 19 }
-
8.数组元素的二分法查找
二分法基本思想:
1.确定该区间的中点位置:mid=(low+high)/2 (mid代表区间中间的结点的位置,low代表区间最左结点位置,high代表区间最右结点位置)
2.将待查a值与结点mid的关键字(下面用R[mid].key)比较,若相等,则查找成功,否则确定新的查找区间:如果R[mid].key>a,则由表的有序性可知,
R[mid].key右侧的值都大于a,所以等于a的关键字如果存在,必然在R[mid].key左边的表中。这时high=mid-1;如果R[mid].key<a,则等于a的关键字如果存在,
必然在R[mid].key右边的表中。这时low=mid+1;如果R[mid].key=a,则查找成功。
3.下一次查找针对新的查找区间,重复步骤(1)和(2)
4.在查找过程中,low逐步增加,high逐步减少,如果low>high,则查找失败。
注:虽然二分法查找的效率高,但是要将表按关键字排序。而排序本身是一种很费时的运算,所以二分法比较适用于顺序存储结构。为保持表的有序性,
在顺序结构中插入和删除都必须移动大量的结点。因此,二分查找特别适用于那种一经建立就很少改动而又经常需要查找的线性表。
所以说用折半查找时序列必须是有序的!
代码例子:
1 public static void main(String[] args) { 2 3 int[] arr=new int[10]; 4 5 for (int i = 0; i < arr.length; i++) {//赋值,为有序数组(1~10) 6 7 arr[i]=i+1; 8 9 } 10 11 int low=0; 12 13 int high=arr.length; 14 15 int key=0; 16 17 while (low<=high) { 18 19 int mid=(low+high)/2; 20 21 if (key==arr[mid]) { 22 23 System.out.println("此数值在arr中的位置为:"+mid); 24 25 break; 26 27 } 28 29 if(key>arr[mid]){ 30 31 low=mid+1; //当小于时,是low指针向后移动,high指针不变 32 33 } 34 35 if(key<arr[mid]){ 36 37 high=mid-1; //当小于时,是low指针向后移动,high指针不变 38 39 } 40 41 43 } 44 45 if(low>high){ 46 47 System.out.println("没有查到结果!"); 48 49 } 50 51 }
-
9.数组元素的选择排序
每次都从待排序的元素中找到最小的或者最大的元素 与待排序的元素中最左侧元素交换位置,
即每轮循环都会挑出剩余元素中最小或最大的元素放在余下元素的最左侧
首先遍历集合中的每个位置的元素,然后将该位置元素与其后面的每一个元素逐一进行比较
例子:
定义数组 int[] a={3,9,0,-9,10} ;
i==0
a[0]=3 a[0]位置的元素 与其之后的每一个元素比较
a[0]和a[1] (3和9)比较结果为 3,9,0,-9,10 (3<9 位置不变)
a[0]和a[2](3和0)比较结果为 0,9,3,-9,10 (3>0 交换位置)
a[0]和a[3] (0和-9)比较结果为 -9,9,3,0,10 (0>-9 交换位置)
a[0]和a[4] (-9和10)比较结果为 -9,9,3,0,10 (-9<10 位置不变)
此时a[0] 位置的元素是最小的,就不用再参与比较了
以此类推
i==1 a={-9,9,3,0,10}
a[1]=9 a[1]位置的元素与其之后的每一个元素比较
a[1]和a[2](9和3)比较结果为 -9,3,9,0,10
a[1]和a[3] (3和0)比较结果为 -9,0,9,3,10
a[1]和a[4] (0和10)比较结果为 -9,0,9,3,10
此时a[1]位置的元素也不用再比了
i==2 a={-9,0,9,3,10}
a[2]=9 a[2]位置的元素与其之后的每一个元素比较
a[2]和a[3] (9 和3)比较结果为 -9,0,3,9,10
a[2]和a[4] (3和10)比较结果为 -9,0,3,9,10
此时只需比较 a[3]和a[4]位置的元素大小即可
i==3 a={-9,0,3,9,10}
a[3]和a[4]比较 ,位置不变 -9,0,3,9,10
1 public static void main(String[] args) { 2 5 int[] array = { 3, 9, 0, -9, 10 }; 6 9 // 遍历每一个位置的元素(最后一个就不需要了) 10 11 for (int i = 0; i < array.length - 1; i++) { 12 13 // 将该位置元素与其后面的每一个元素逐一进行比较 14 15 for (int j = i + 1; j < array.length; j++) { 16 17 if (array[i] > array[j]) { 18 19 int temp = array[i]; 20 21 array[i] = array[j]; 22 23 array[j] = temp; 24 25 } 26 27 } 28 29 } 30 31 33 for (int a : array) { 34 35 System.out.println(a); 36 37 } 38 39 }
-
10.数组元素的冒泡排序
即数组中相邻两个元素进行比较,每一轮的比较都会将待排序的元素中较大(或较小)的元素值放在所有待排序的元素最后
例子:
定义数组a ={10,2,19,-9,1 }
i==0时
a[0]与a[1]比后结果为 2,10,19,-9,1
a[1]与a[2]比后结果为 2,10,19,-9,1
a[2]与a[3]比后结果为 2,10,-9,19,1
a[3]与a[4]比 后结果为2,10,-9,1,19 —– 此时a[4]最大 不用再参与比较
i==1时 a={2,10,-9,1,19}
a[0]与a[1]比后结果为 2,10,-9,1,19
a[1]与a[2]比后结果为 2,-9,10,1,19
a[2]与a[3]比后结果为 2,-9,1,10,19 —– 此时a[3]最大 不用再参与比较
i==2时 a={2,-9,1,10,19}
a[0]与a[1]比后结果为 -9,2,1,10,19
a[1]与a[2]比后结果为 -9,1,2,10,19 ——此时a[2]最大 不用再参与比较
i==3时 a={-9,1,2,10,19} —–只需比较a[0]和a[1]
a[0]与a[1]比后结果为 -9,1,2,10,19
代码:
1 public static void main(String[] args) { 2 3 4 5 //定义数组 6 7 int[] array ={10,2,19,-9,1 }; 8 9 //外层循环控制次数 10 11 for (int i = 0; i< array.length-1; i++) { 12 13 for (int j = 0; j < array.length-i-1; j++) { 14 15 //相邻两个元素作比较,如果是从大到小排序则 用array[j]<array[j+1] 16 17 if(array[j] > array[j+1]){ 18 19 //如果array[j]>array[j+1],则二者交换位置。将大的往后放 20 21 int temp = array[j+1]; 22 23 array[j+1] = array[j]; 24 25 array[j] = temp; 26 27 } 28 29 } 33 } 34 35 //最后遍历数组输出结果为 -9,1,2,10,19 36 37 for (int i = 0; i < array.length; i++) { 38 39 System.out.print(array[i]+" "); 40 41 } 45 }
-
11.Arrays工具类的使用
java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。
具有以下功能:
给数组赋值:通过 fill 方法。
对数组排序:通过 sort 方法,按升序。
比较数组:通过 equals 方法比较数组中元素值是否相等。
查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。
使用例子:
1 public static void main(String[] args) { 2 3 int a[]={20,3,32,1,72,26,35}; 6 7 int b[]={3,5,7,8,54,23,9}; 8 9 int c[]={3,5,7,8,54,23,9}; 10 11 System.out.println("转换前:"+a); 12 13 //数组转换字符串 14 15 String str=Arrays.toString(a); 16 17 System.out.println("转换为字符串:"+str); 18 19 //对数组array的元素进行升序排列 20 21 System.out.println("原数组:"+Arrays.toString(a)); 22 23 Arrays.sort(a); 24 25 System.out.println("排序后:"+Arrays.toString(a)); 26 27 //所以元素都赋成特定值 28 29 System.out.println("赋值前:"+Arrays.toString(a)); 30 31 Arrays.fill(a,10); 32 33 System.out.println("赋值后:"+Arrays.toString(a)); 34 35 //判断两个数组是否相等(对应位置上的元素是否相等) 36 37 boolean boo=Arrays.equals(a,b); 38 39 boolean boo2=Arrays.equals(b, c); 40 41 System.out.println("a:"+Arrays.toString(a)); 42 43 System.out.println("b:"+Arrays.toString(b)); 44 45 System.out.println("c:"+Arrays.toString(c)); 46 47 System.out.println("a与b是否相等?"+boo); 48 49 System.out.println("b与c是否相等?"+boo2); 50 51 //把数组复制成特定长度的数组 52 53 int d[]=Arrays.copyOf(b,b.length); 54 55 System.out.println("d:"+Arrays.toString(d)); 56 57 System.out.println("b:"+Arrays.toString(b)); 58 59 //查询数组下标 60 61 int i=Arrays.binarySearch(b, 5); 62 63 System.out.println("数组b第5个数字下标是:"+i); 64 65 //数组转换成字符串 66 67 String str2 = Arrays.toString(a); 68 69 //字符串转换成集合 70 71 List<String> list = Arrays.asList(str2); 72 73 for (int j = 0; j < list.size(); j++) { 74 75 System.out.println("转换后的List集合:"+list.get(j)); 76 77 } 78 79 80 81 }
-
12.二维数组的介绍
二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组,例如:
String str[][] = new String[3][4]; //定义了一个字符串类型的二维数组,其中包含三个一维数组,每个一维数组可以存放四个字符串
-
13.二维数组的声明与初始化
定义格式: 数据类型[][] 数组名 或者
数据类型 数组名[][]
二维数组的初始化:
1.静态初始化 如:int arr[][]={{1,2},{2,3},{3,4,5}}; (Java中,数组空间不是连续分配的,所有可以不要求二维数组每一维的大小相同。)
2.动态初始化 格式:数据类型[][] 数组名 = new 数据类型[二维数组的长度/包含的一维数组的个数][每个一维数组的长度];
如:int arr[][] = new arr[3][4];
arr[0]----下标为0的位置上一维数组
arr[1][3]-----如果要获取具体的元素需要两个下标
int[][] arr = new int[3][]; //数组中每个一维数组长度不确定
二维数组错误的初始化:
1.int [][]i = new int[][];
2.int [][]i = new int[][5];
-
14.二维数组的遍历(两种)
1 public static void main(String[] args) { 2 3 int[][] arr = {{1,2,3},{4,5},{6}}; 4 7 //调用方法1 8 9 printArr1(arr); 10 11 System.out.println("------"); 12 13 //调用方法2 14 15 printArr2(arr); 16 17 System.out.println("------"); 18 19 } 20 21 22 23 //方法1 24 25 public static void printArr1(int[][] arr) { 26 27 for(int x=0; x<arr.length; x++) { 28 29 for(int y=0; y<arr[x].length; y++) { 30 31 System.out.print(arr[x][y]+" "); 32 33 } 34 35 System.out.println(); 36 37 } 38 39 } 43 //方法2 44 45 public static void printArr2(int[][] arr) { 46 47 //遍历二维数组中每一个一维数组 48 49 for(int[] cells : arr) { 50 51 //遍历一维数组中每一个元素 52 53 for(int cell : cells) { 54 55 System.out.print(cell+" "); 56 57 } 58 59 System.out.println(); 60 61 } 62 63 }
-
15.二维数组的使用
int[][] i=new int[3][4];
二维数组的引用:
通过数组的索引值
i[0][0]第一个数组元素值的第一个值
i[1][2]第二个数组元素值的第三个值
二维数组的长度:
以上面的为例:
System.out.println(i.length);//二维数组的长度(行的长度)==3
System.out.println(i[0].length);//i数组中第一个数组值的长度(列的长度)==4
二维数组使用实例(杨辉三角):
1 public static void main(String[] args) { 2 3 //从控制台获取行数 4 5 Scanner s = new Scanner(System.in); 6 7 int row = s.nextInt(); 8 9 //根据行数定义好二维数组,由于每一行的元素个数不同,所以不定义每一行的个数 10 11 int[][] arr = new int[row][]; 12 13 //遍历二维数组 14 15 for(int i = 0; i < row; i++){ 16 17 //初始化每一行的这个一维数组 18 19 arr[i] = new int[i + 1]; 20 21 //遍历这个一维数组,添加元素 22 23 for(int j = 0; j <= i; j++){ 24 25 //每一列的开头和结尾元素为1,开头的时候,j=0,结尾的时候,j=i 26 27 if(j == 0 || j == i){ 28 29 arr[i][j] = 1; 30 31 } else {//每一个元素是它上一行的元素和斜对角元素之和 32 33 arr[i][j] = arr[i -1][j] + arr[i - 1][j - 1]; 34 35 } 36 37 System.out.print(arr[i][j] + "\t"); 38 39 } 40 41 System.out.println(); 42 43 } 44 45 }
参考网址:
java学习路线:https://jingyan.baidu.com/article/c1a3101e110864de656deb83.html?qq-pf-to=pcqq.c2c
数组定义访问与遍历:https://www.runoob.com/java/java-array.html
数组优缺点:https://blog.csdn.net/blog_zyx/article/details/76216415
数组动态静态初始化:https://blog.csdn.net/chenzuen113113/article/details/79960895
数组存储机制:https://blog.csdn.net/lin_tuer/article/details/82967516
Java中的堆和栈参考地址:https://www.cnblogs.com/ibelieve618/p/6380328.html
顺序查找:https://blog.csdn.net/lee514/article/details/82977528
数组二分法:https://blog.csdn.net/qq_29073921/article/details/88861851
选择冒泡排序:https://blog.csdn.net/weixin_41005006/article/details/80643326
arrays工具类的使用:https://blog.csdn.net/qq_39629277/article/details/85052679
二维数组的概念:https://www.cnblogs.com/zhouguanglin/p/7210129.html
二维数组遍历使用:https://blog.csdn.net/north_q/article/details/80798349
二维数组的使用:https://blog.csdn.net/Futureing/article/details/82559230