数组 数组定义和访问 容器的概念 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 变量中只能存储一个数据,新的数据进来,老的数据将被替换,如果需要存储多个数据,需要使用容器。 容器概念 容器:是将多个数据存储到一起,每个数据称为该容器的元素。 生活中的容器:水杯,衣柜,鞋柜,教室 数组: 1. 概念: java中的数组就是一个容器,可以存储多个数据,但是数据的类型必须一致 2. 特点: (1 )可以存储多个数据 (2 )多个数据的类型必须保持一致 (3 )数组一旦创建,长度是永远不可以发生改变 (4 )创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址 public class Demo01Box { public static void main (String[] args) { int num = 10 ; System.out.println(num); num = 20 ; System.out.println(num); int a = 80 ; int b = 90 ; int c = 70 ; int d = 50 ; int e = 85 ; int f = 95 ; int g = 59 ; int h = 63 ; int sum = a + b + c + d + e + f + g + h; int avg = sum/80 ; } }
数组变量的定义 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 1. 数组变量定义格式一: ---------------推荐使用------------- 数据类型[] 一维数组名称; 数据类型[][] 二维数组名称; 2. 数组变量定义格式二: 数据类型 数组名称[]; 1. 定义一个存储int 类型数组的变量arrayA2. 定义一个存储double 类型数组的变量arrayB3. 定义一个存储char 类型数组的变量arrayC public class Demo02Array { public static void main (String[] args) { int num; int [] arrayA; double arrayB[]; char [] arrayC; } }
图解:
数组的第一种初始化方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 1. 创建一个int 类型的数组,可以存储3 个int 数据,给该数组起个名称叫做arrayA2. 创建一个double 类型的数组,可以存储7 个double 数据,给该数组起个名称叫做arrayB3. 创建一个char 类型的数组,可以存储5 个char 数据,给该数组起个名称叫做arrayC 数组的第一种初始化方式(动态初始化: 指定数组的长度) 1. 格式: 数据类型[] 数组名称 = new 数据类型[长度]; 2. 格式解释: (1 )左侧数据类型: 规定了数组中可以存储哪种类型的数据 (2 )左侧[]: 表示数组的意思 (3 )数组名称: 就是给数组起个名字(相当于门牌号),方便找到并使用数组 (4 )=: 表示赋值,把具体的=右边new 出来的数组容器, 存储到=左边的数组变量中,但是存储的是数组在内存空间的地址值 (5 )new : 创建数组容器的过程 (6 )右侧数据类型: 和左侧保持一致 (7 )右侧[]中长度: 是一个int 数字,表示数组中可以存储数据的数量,也叫作数组长度 3. 练习: (1 )创建一个int 类型的数组,可以存储3 个int 数据,给该数组起个名称叫做arrayA (2 )创建一个double 类型的数组,可以存储7 个double 数据,给该数组起个名称叫做arrayB (3 )创建一个char 类型的数组,可以存储5 个char 数据,给该数组起个名称叫做arrayC public class Demo03Array { public static void main (String[] args) { int [] arrayA = new int [3 ]; double [] arrayB = new double [7 ]; char [] arrayC = new char [5 ]; } }
数组的第二种初始化方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 数组的第二种初始化方式(标准格式静态初始化:指定数组中的每个元素) 1. 格式: 数据类型[] 数组名称 = new 数据类型[]{元素1 ,元素2 ,元素3 ,...元素n}; 2. 注意: (1 )右侧[]中不能写长度: JVM会根据{}中元素的数量计算/推导出数组的长度 只要右侧[]中写长度,就会报错 (2 ){}中的每个元素之间有逗号(英文状态)隔开,最后一个元素后面没有逗号 3. 练习: (1 )创建一个int 类型的数组,可以存储多个int 数据100 ,200 ,300 ,给该数组起个名称叫做arrayA (2 )创建一个double 类型的数组,可以存储多个double 数据1.1 ,2.2 ,3.3 ,4.4 ,5.5 ,6.6 ,7.7 ,给该数组起个名称叫做arrayB (3 )创建一个char 类型的数组,可以存储多个char 数据'真' ,'的' ,'好' ,'想' ,'你' ,给该数组起个名称叫做arrayC public class Demo04Array { public static void main (String[] args) { int [] arrayA = new int []{100 ,200 ,300 }; double [] arrayB = new double []{1.1 ,2.2 ,3.3 ,4.4 ,5.5 ,6.6 ,7.7 }; char [] arrayC = new char []{'真' ,'的' ,'好' ,'想' ,'你' }; } }
数组的第三种初始化方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 数组的第三种初始化方式(简化格式静态初始化:指定数组中的每个元素) 1. 格式: 数据类型[] 数组名称 = {元素1 ,元素2 ,元素3 ,...元素n}; 2. 练习: (1 )创建一个int 类型的数组,可以存储多个int 数据100 ,200 ,300 ,给该数组起个名称叫做arrayA (2 )创建一个double 类型的数组,可以存储多个double 数据1.1 ,2.2 ,3.3 ,4.4 ,5.5 ,6.6 ,7.7 ,给该数组起个名称叫做arrayB (3 )创建一个char 类型的数组,可以存储多个char 数据'真' ,'的' ,'好' ,'想' ,'你' ,给该数组起个名称叫做arrayC 3. 注意: (1 )右侧不用写长度,JVM根据{}中数组元素的数量推导长度 (2 )虽然没有写new ,底层仍然有new 的过程 (3 )动态初始化和标准格式的静态初始化,可以分两步完成 (4 )简化格式静态初始化,不能分成两步完成 public class Demo05Array { public static void main (String[] args) { int [] arrayA = {100 ,200 ,300 }; double [] arrayB = {1.1 ,2.2 ,3.3 ,4.4 ,5.5 ,6.6 ,7.7 }; char [] arrayC = {'真' ,'的' ,'好' ,'想' ,'你' }; int num; num = 10 ; System.out.println(num); num = 100 ; System.out.println(num); System.out.println("-------------------" ); int [] arr; arr = new int [3 ]; arr = new int []{10 ,20 ,30 }; System.out.println("-------------------" ); int [] arr2; } }
数组的使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 简化格式静态初始化数组的使用 1. 数组名称: 代表数组在内存空间的地址值,是一个十六进制的整数数字 2. 索引编号:是一个整数数字 数组中的每个数据,称之为数组元素 数组为每个元素进行编号(专业术语叫做索引),该编号从0 开始到最大值(数组长度 减 1 ) 3. 数组元素: 数组名称[索引编号] 举例: array[3 ]: 数组array中索引编号为3 的元素 4. 获取数组长度: 数组内部有个length属性,专门记录数组的长度 数组名称.length: 是一个int 数字,代表数组的长度 public class Demo06ArrayUse { public static void main (String[] args) { int [] array = {10 ,20 ,30 }; System.out.println(array); System.out.println(array[0 ]); System.out.println(array[1 ]); System.out.println(array[2 ]); System.out.println("--------------" ); array[0 ] = 100 ; array[1 ] = 200 ; array[2 ] = 300 ; System.out.println(array[0 ]); System.out.println(array[1 ]); System.out.println(array[2 ]); int count = array.length; System.out.println("数组长度: " +count); System.out.println("数组长度: " +array.length); System.out.println(array[array.length-1 ]); } }
注意点:
3.数组元素的默认初始化值,new出来在堆中的都有默认值
数组元素是整形:0
数组元素是浮点型:0.0
数组元素是char型:0
1 2 (注意不是'0' ,而是数0 ,ASCII码或'\u0000' ,表现为空) if (char [0 ] == 0 ) true
数组元素是boolean型,false
数组元素是引用类型,null
4.索引:java中的索引基本上都是从0开始的
除了mysql的column是从1开始的。
5.数组是引用类型,数组型数据是对象[Object],数组中的每个对象相当于该对象的成员变量。(数组一经分配空间,元素按照成员变量同样的方式被隐式初始化)
6.int[] a = new int[0];a[0] = 10;// 运行报错,a没有长度,越界异常
7.数组简写形式不能作为实参,int[] a = {1,2};只能一次性定义时使用
1 2 3 4 把{1 ,2 }当成形参就是int a; a = {1 ,2 }; 如果数组初始化中不使用运算符new 。需要注意:下列写法是错误的。 int [] arr;arr={1 ,2 ,3 ,4 ,5 };
8.数组的最大索引值为(数组名.length-1)
数组应用场景
如果需要存储大量的数据,例如如果需要读取100个数,那么就需要定义100个变量,显然重复写100次代码,是没有太大意义的。这时候就可以用数组。
当元素较多时为了方便操作这些数组,会先进行来临时存储,所使用的容器就是数组。
数组原理内存图 java中的内存分配 1 2 3 4 5 6 7 1. 方法区: 存储可以运行的class文件。 静态区(优先于对象创建,随类的加载而加载静态内容) 2. 方法栈(stack): 方法运行时使用的内存,比如main方法运行,进入方法栈中执行。3. 堆内存(heap): 存储对象或者数组,new 来创建的,都存储在堆内存。 常量池(String双引号的常量和new 的常量位置不一样) 4. 寄存器: 给CPU使用 5. 本地方法栈: JVM在使用操作系统功能的时候使用,
内存结构简化图:
图解:
一个数组内存图 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class Demo01OneArray { public static void main (String[] args) { int [] one = new int [2 ]; System.out.println(one); System.out.println(one[0 ]); System.out.println(one[1 ]); one[0 ] = 10 ; one[1 ] = 20 ; System.out.println(one); System.out.println(one[0 ]); System.out.println(one[1 ]); } }
图解:
两个数组内存图 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public class Demo02TwoArray { public static void main (String[] args) { int [] one = new int [2 ]; System.out.println(one); System.out.println(one[0 ]); System.out.println(one[1 ]); one[0 ] = 10 ; one[1 ] = 20 ; System.out.println(one); System.out.println(one[0 ]); System.out.println(one[1 ]); System.out.println("--------------" ); int [] two = new int [2 ]; System.out.println(two); System.out.println(two[0 ]); System.out.println(two[1 ]); two[0 ] = 100 ; two[1 ] = 200 ; System.out.println(two); System.out.println(two[0 ]); System.out.println(two[1 ]); } }
图解:省略,就是把一个对象的内存图复制两份,每个数组之间没有任何关系
两个变量指向一个数组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 public class Demo03SameArray { public static void main (String[] args) { int [] one = new int [2 ]; System.out.println(one); System.out.println(one[0 ]); one[0 ] = 10 ; System.out.println(one); System.out.println(one[0 ]); System.out.println("--------------" ); int [] two = one; System.out.println(two); System.out.println(two[0 ]); two[0 ] = 100 ; System.out.println(two); System.out.println(two[0 ]); System.out.println(one[0 ]); } }
图解:
数组操作的常见问题 数组越界异常 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class Demo01ArrayProblem { public static void main (String[] args) { int [] one = {100 ,200 ,300 }; System.out.println(one); System.out.println(one[0 ]); System.out.println(one[1 ]); System.out.println(one[2 ]); } }
图解:
数组空指针异常 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class Demo02ArrayProblem { public static void main (String[] args) { int [] one = {100 ,200 ,300 }; System.out.println(one); System.out.println(one[0 ]); System.out.println(one[1 ]); System.out.println(one[2 ]); one = null ; System.out.println(one); } }
图解:
数组练习 数组遍历 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 数组遍历: 就是将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基石。 public class Demo01EachArray { public static void main (String[] args) { int [] array = {10 ,20 ,30 ,50 }; System.out.println(array[0 ]); System.out.println(array[1 ]); System.out.println(array[2 ]); System.out.println(array[3 ]); System.out.println("-----------" ); for (int i = 0 ; i < 4 ; i++) { System.out.println("索引编号: " +i+", 对应的元素值: " +array[i]); } System.out.println("-----------" ); for (int i = 0 ; i < array.length; i++) { System.out.println(array[i]); } } }
求三个int数字的最大值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 需求: 求三个int 数字的最大值 实现步骤: 1. 定义3 个int 变量a,b,c,并分别初始化 2. 假设变量a的值是最大的,把a保存到int 变量max中 3. 如果变量b的值大于max,说明max中的值目前不是最大的,把b的值赋值给max 4. 如果变量c的值大于max,说明max中的值目前不是最大的,把c的值赋值给max 5. 打印max的值 public class Demo02Max { public static void main (String[] args) { int a = 100 , b = 200 ,c = 300 ; int max = a; if (b > max) { max = b; } if (c > max) { max = c; } System.out.println("最大值: " +max); } }
图解:
数组获取最大值元素 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 需求: 求int 数组元素最大值 实现步骤: 1. 创建int 数组array,并初始化 2. 假设索引为0 的元素是最大的,保存到int 变量max中 3. 使用for 循环依次获取后面的(从索引1 开始)每个元素 3.1 如果当前元素 大于 max 说明max中的值已经不是最大的了 3.2 把当前元素赋值给变量max 4. for 循环结束后打印max的值 public class Demo03ArrayMax { public static void main (String[] args) { int [] array = {5 ,15 ,2000 ,10000 ,100 ,4000 }; int max = array[0 ]; for (int i = 1 ; i < array.length; i++) { if (array[i] > max) { max = array[i]; } } System.out.println("数组最大值: " +max); } }
图解分析:
执行流程:
数组中的常见算法
数组元素的赋值(杨辉三角、回形数等)
求数值型数组中元素的最大值、最小值、平均数、总和等
数组的复制、反转、查找(线性查找、二分法查找)
数组元素的排序算法
杨辉三角 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class $_01_ 杨辉三角 { public static void main (String[] args) { int [][] yangHui = new int [10 ][]; for (int i = 0 ; i < 10 ; i++) { yangHui[i] = new int [i + 1 ]; yangHui[i][0 ] = yangHui[i][i] = 1 ; for (int j = 1 ; j < yangHui[i].length - 1 ; j++) { yangHui[i][j] = yangHui[i - 1 ][j - 1 ] + yangHui[i - 1 ][j]; } } for (int i = 0 ; i < yangHui.length; i++) { for (int j = 0 ; j < yangHui[i].length; j++) { System.out.print(yangHui[i][j] + " " ); } System.out.println(); } } }
回形数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class $_01_ 回形数 { public static void main (String[] args) { int n = 7 ; int [][] arr = new int [n][n]; int count = 0 ; int maxX = n - 1 ; int maxY = n - 1 ; int minX = 0 ; int minY = 0 ; while (minX <= maxX) { for (int x = minX; x <= maxX; x++) { arr[minY][x] = ++count; } minY++; for (int y = minY; y <= maxY; y++) { arr[y][maxX] = ++count; } maxX--; for (int x = maxX; x >= minX; x--) { arr[maxY][x] = ++count; } maxY--; for (int y = maxY; y >= minY; y--) { arr[y][minX] = ++count; } minX++; } for (int i = 0 ; i < arr.length; i++) { for (int j = 0 ; j < arr.length; j++) { String space = (arr[i][j] + "" ).length() == 1 ? "0" : "" ; System.out.print(space + arr[i][j] + " " ); } System.out.println(); } } }
数组最大值、最小值、平均数、总和 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public class $_03_ 数值 { public static void main (String[] args) { int [] arr = new int [10 ]; for (int i = 0 ; i < 10 ; i++) { arr[i] = (int ) (Math.random() * 99 + 10 ); } int maxValue = arr[0 ]; for (int i = 1 ; i < arr.length; i++) { if (maxValue < arr[i]) { maxValue = arr[i]; } } System.out.println("最大值为:" + maxValue); int minValue = arr[0 ]; for (int i = 1 ; i < arr.length; i++) { if (minValue > arr[i]) { minValue = arr[i]; } } System.out.println("最小值为:" + minValue); int sum = 0 ; for (int i = 0 ; i < arr.length; i++) { sum += arr[i]; } System.out.println("和值:" + sum); System.out.println("平均值为:" + (sum / arr.length)); } }
数组复制 1 2 3 4 5 6 7 8 9 10 11 public class $_04_ 数组复制 { public static void main (String[] args) { String[] arr = new String []{"JJ" ,"DD" ,"MM" ,"GG" ,"NN" }; String[] arr1 = new String [arr.length]; for (int i = 0 ; i < arr1.length; i++) { arr1[i] = arr[i]; } } }
数组反转 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class $_05_ 数组反转 { public static void main (String[] args) { String[] arr = new String []{"JJ" , "DD" , "MM" , "GG" , "NN" }; for (int i = 0 ; i < arr.length / 2 ; i++) { String temp = arr[i]; arr[i] = arr[arr.length - 1 - i]; arr[arr.length - 1 - i] = temp; } System.out.println(Arrays.toString(arr)); for (int i = 0 , j = arr.length - 1 ; i < j; i++, j--) { String temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } System.out.println(Arrays.toString(arr)); } }
线性查找/搜索 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class $_05_ 数组查找 { public static void main (String[] args) { String[] arr = new String []{"JJ" , "DD" , "MM" , "GG" , "NN" }; String search = "BB" ; boolean flag = true ; for (int i = 0 ; i < arr.length; i++) { if (search.equals(arr[i])) { System.out.println("找到了指定的元素,位置位:" +i); flag = false ; break ; } } if (flag) { System.out.println("没有找到" ); } } }
二分法查找
比线性查找快;
前提:要查找的数组必须有序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class $_05_ 数组查找 { public static void main (String[] args) { int [] arr = new int []{-99 , -54 , -2 , 0 , 2 , 33 , 43 , 256 , 999 }; boolean isFlag = true ; int number = 43 ; int head = 0 ; int end = arr.length - 1 ; while (head <= end) { int middle = (head + end) / 2 ; if (number == arr[middle]) { System.out.println("找到元素,位置位 :" + middle); isFlag = false ; break ; } else if (arr[middle] > number) { end = middle - 1 ; } else { head = middle + 1 ; } } if (isFlag) { System.out.println("没有找到" ); } } }