含义:
存储同一种数据类型多个元素的固定容器
前提条件:
1.数组一旦初始化,数组在内存中的长度固定不变
2.数组中的元素在内存中必须是同一种数据类型
3.数组中的元素在内存中必须是多个,如果初始化可以存储0个元素和1个元素的数组
也不会编译报错,只不过这样的数组没有任何意义
数组的声明
含义:
定义数组
格式:
数据类型[] 数组名;(推荐)
数据类型 数组名[];
解释:
数据类型:数组中元素的数据类型
[]:定义的是数组
数据类型[]:数组的数据类型
数组名:数组的名字
数组的初始化
分类:
动态初始化
在初始化数组时,只会初始化数组的大小(长度),不会初始化数组中具体存储的元素,JVM可以直接获取到数组的长度
静态初始化
在初始化数组时,不会初始化数组的大小(长度),只会初始化数组中具体存储的元素,JVM可以间接获取到数组的长度
格式:
动态初始化:
数据类型[] 数组名 = new 数据类型[长度];
静态初始化:
标准版:
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,......,元素n};
简化版:
数据类型[] 数组名 = {元素1,元素2,......,元素n};
备注:JVM会根据数组名前面的数据类型[]隐式填充new 数据类型[]
解释:
new:向JVM内存申请并开辟内存空间
数据类型:数组中元素的数据类型
长度:数组的大小
//动态初始化
int[] arr01 = new int[3];
//静态初始化(标准版)
int[] arr02 = new int[]{11,22,33};
//静态初始化(简化版)
int[] arr03 = {11,22,33};
数组声明初始化的注意事项:
1.数组中元素支持类型的转换
2.数组不支持动静结合的方式进行数组的初始化
3.进行数组的动态初始化时,数组的长度只能是正整数(长度为0的数组没有任何意义)
4.数组静态初始化的简化版不可以先声明后初始化;
原因:数组静态初始化的标准版会根据数组名前面的数据类型[]隐式填充"new 数据类型[]",数组静态初始化的简化版
先声明后初始化时无法直接获取数组名前面的数据类型
int[] arr01 = {11,22,33,'a'};
int[] arr02 = {11,22,33,(int)3.14};
//int[] arr03 = new int[3]{11,22,33};//错误
//int[] arr04 = new int[-3];//数组初始化异常
int[] arr05;
arr05 = new int[3];
int[] arr06;
arr06 = new int[]{11,22,33};
int[] arr07;
//arr07 = {11,22,33};错误
数组的访问
分类:
获取数组中指定元素
获取数组中元素个数
获取数组中指定元素
如果访问数组中的元素必须通过数组的索引值进行获取和访问
索引值:
含义:
JVM针对数组中的元素进行动态的数字编号
特点:
1.长度为0的数组不存在索引值
2.索引值从0开始,依次类推,最大的索引值为数组的长度-1
格式:
赋值格式:
数组名[索引值] = 元素值;
获取格式:
数组名[索引值]
注意:
进行数组元素的赋值和获取时,索引值如果非法或不存在,编译不会报错,但是在
运行时进行访问或获取的时候,发生
ArrayIndexOutOfBoundsException(数组索引越界异常)
//声明并初始化数组
int[] arr = {11,22,33};
System.out.println(arr);
//[I@1b6d3586,这个东西就是数组值(地址值,并非内存地址值,内存地址值是物理地址,
// 地址值是人工模拟的内存地址值)
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
获取数组中元素个数
格式:
数组名.length
//声明初始化数组
int[] arr = {11,22,33};
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println("=========================");
for (int i = 0; i < 3; i++) {
System.out.println(arr[i]);
}
System.out.println("=========================");
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
数组的应用
基础应用:
不改变数组中元素位置的基础上,进行查询 *** 作
例如:
求和,求最值,......
高级应用
针对数组中元素的索引位置进行改变,进行所需的 *** 作
例如:
反转,排序
综合应用
在数组的 *** 作的基础上加入方法或其它知识点,进行综合 *** 作
例如:
二分查找,动态 *** 作,......
按照固定的格式拼接数组中的元素
固定格式:
数组:[元素1, 元素2, ......,元素n]
//创建数组
int[] arr = {11,22,33,44,55};
System.out.print("数组:[");
//遍历数组
for (int i = 0; i < arr.length; i++) {
//判断是否为最后一个元素
if (i == arr.length - 1) {
System.out.println(arr[i] + "]");
} else {
System.out.print(arr[i] + ", ");
}
}
获取数组中所有元素的累加和
//创建数组
int[] arr = {11,22,33};
//声明并初始化求和变量
int sum = 0;
//遍历数组
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
//打印求和变量
System.out.println("sum = " + sum);
获取数组中所有元素的最大值
//声明并初始化数组
int[] arr = {5,15,2000,10000,100,4000};
//声明并初始化最大值变量
int max = arr[0];
//遍历数组
for (int i = 1; i < arr.length; i++) {
//进行比较
if (max < arr[i]) {
max = arr[i];
}
}
//打印最大值变量
System.out.println("max = " + max);
分析以下需求,并用代码实现:
(1)在编程竞赛中,有10位评委为参赛的选手打分,分数分别为:5,4,6,8,9,0,1,2,7,3
(2)求选手的最后得分(去掉一个最高分和一个最低分后其余8位评委打分的平均值)
//声明并初始化数组保存评委分数
int[] arr = {5,4,6,8,9,0,1,2,7,3};
//获取10位评委的总分
//获取10位评委的最高分
//获取10位评委的最低分
int sum = arr[0];
int max = arr[0];
int min = arr[0];
//遍历数组
for (int i = 1; i < arr.length; i++) {
sum += arr[i];
if (max < arr[i]) {
max = arr[i];
}
if (min > arr[i]) {
min = arr[i];
}
}
//获取选手最后得分
double avg = (sum - max - min) * 1.0 / (arr.length - 2);
System.out.println("avg = " + avg);
获取指定元素在数组中出现的第一次索引
//声明并初始化数组
int[] arr = {11,22,33,44,55,22,45,22,54,22};
//声明并初始化索引
int index = -1;
//声明并初始化指定元素
int num = 22;
//遍历数组
for (int i = 0; i < arr.length; i++) {
if (num == arr[i]) {
index = i;
break;
}
}
//打印索引
if (index == -1) {
System.out.println("指定元素在数组中没有出现......");
} else {
System.out.println("指定元素在数组中出现的第一次索引是:" + index);
}
数组的反转
将数组首尾对应的元素进行索引位置的互换
反转前:[11, 22, 33, 44, 55]
反转后:[55, 44, 33, 22, 11]
分析:
1.首次进行首尾互换元素的索引位置
int i = 0;
int j = arr.length - 1;
2.首尾互换元素索引位置 *** 作的规律
i++,j--
3.如何进行元素的互换
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
4.互换元素的前提条件?
如果数组长度为奇数个时: i < j
如果数组长度为偶数个时: i < j
//声明并初始化数组
int[] arr = {11,22,33,44,55};
System.out.print("反转前:[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
System.out.println(arr[i] + "]");
} else {
System.out.print(arr[i] + ", ");
}
}
//反转 *** 作
for (int i = 0 , j = arr.length - 1 ; i < j ; i++ , j--) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
System.out.print("反转后:[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
System.out.println(arr[i] + "]");
} else {
System.out.print(arr[i] + ", ");
}
}
优化
5.i和j的关系:
i + j = arr.length - 1;
j = arr.length - 1 - i;
6.优化i < arr.length - 1 - i
i + i < arr.length - 1
2 * i < arr.length - 1
i < arr.length/2 - 1/2
i < arr.length/2
//反转 *** 作
for (int i = 0; i < arr.length/2 ; i++) {
int temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
数组的排序
按照某种排序规则让数组中元素从小到大或从大到小依次排列
排序算法分类:
冒泡排序
选择排序
希尔排序
归并排序
快速排序
插入排序
......
冒泡排序:求最大值排序
分析:
原理:将相邻两个整数进行比较,将较大值移动到右侧
考虑到一次循环无法获取排序后的数组,需要使用循环嵌套
外层循环变量:求最大值的次数
内层循环变量:求一次最大值需要比较的次数
//排序 *** 作
//外层循环变量:求最大值的次数
for (int count = 1; count < arr.length ; count++) {
//内层循环变量:求一次最大值需要比较的次数
/*
数组长度为6,需要进行5次求最大值
第1次交换最大值至最右侧,比较的循环次数为5(6 - 1)
第2次交换最大值至剩余元素最右侧,比较的循环次数为4(6 - 2)
第3次交换最大值至剩余元素最右侧,比较的循环次数为3(6 - 3)
第4次交换最大值至剩余元素最右侧,比较的循环次数为2(6 - 4)
第5次交换最大值至剩余元素最右侧,比较的循环次数为1(6 - 5)
*/
for (int i = 0; i < arr.length - count; i++) {
if (arr[i] > arr[i+1]) {
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
}
优化
//排序 *** 作
//外层循环变量:求最大值的次数
for (int count = 1; count < arr.length; count++) {
//声明并初始化临时最大值索引(获取最大值存储的索引位置)
int index = arr.length - count;
/*
数组长度为6,需要进行5次求最大值
第1次比较最大值是否在index处,比较的循环次数为5(6 - 1)
第2次比较剩余数据最大值是否在index处,比较的循环次数为4(6 - 2)
第3次比较剩余数据最大值是否在index处,比较的循环次数为3(6 - 3)
第4次比较剩余数据最大值是否在index处,比较的循环次数为2(6 - 4)
第5次比较剩余数据最大值是否在index处,比较的循环次数为1(6 - 5)
*/
for (int i = 0; i < arr.length - count; i++) {
System.out.println(arr[index] + "<" + arr[i]);
if (arr[index] < arr[i]) {
index = i;
}
}
System.out.println("===========");
//进行元素位置的互换
if (index != arr.length - count) {
int temp = arr[arr.length - count];
arr[arr.length - count] = arr[index];
arr[index] = temp;
}
}
数组和方法使用时的健壮性判断:
1.当方法的形式是引用类型时,需要在方法内部针对该参数进行非空校验,如果使用null调用任何内容,会发生空指针异常NullPointerException
2.除了引用类型还需要根据实际需求判断方法其它的实参
int[] arr = {11,22,33,44,55};
int num = getNum(arr,9);
System.out.println(num);
public static int getNum (int[] arr , int index) {
//非空校验
if (arr == null) {
return 0;
}
//数组非法索引判断
if (index < 0 || index >= arr.length) {
return 0;
}
int num = arr[index];
return num;
}
方法传递参数时的特点:
当方法的形参是基本类型时:
1.参数传递的内容是该基本类型的数据值
2.形式参数数据值的改变不会影响实际参数的数据值
当方法的形参是引用类型时:
1.参数传递的内容是该引用类型的地址值
2.形式参数地址值的改变不会影响实际参数的地址值
3.形式参数地址值不变,形式参数地址值中内容的改变影响实际参数地址值中内容
可变参数(JDK5.0)
含义:
调用方法时传递实参可以任何个数的形参(其实就是一个根据实参内容进行静态初始化的数组)
好处:
简化部分情况下的重载
位置:
方法的形参列表中
格式:
数据类型... 可变参数名
public static void main(String[] args) {
method(11,22,33,44,55,66,77,88);
}
public static void method (int... a) {
System.out.println(a);//[I@1b6d3586
System.out.println(a.length);
System.out.println(a[0]);
}
可变参数的注意事项:
1.当方法的形参列表中除了可变参数外还存在其它参数,需要将可变参数写在形参列表的最后
2.方法的形参列表中最多只能含有一个可变参数
public static void main(String[] args) {
method("HelloWorld",11,22,33,44,55);
}
public static void method (String str , int... arr) {}
获取指定元素在数组中出现的第一次索引
二分查找法(折半查找法)
前提条件:待 *** 作的数组必须是元素大小有序的数组
public static void main(String[] args) {
//声明并初始化数组
int[] arr = {2,5,7,8,10,15,18,20,22,25,28};//数组必须是有序的
//声明并初始化指定元素
int num = 18;
int index = getIndex(arr, num);
//打印索引
if (index == -1) {
System.out.println("指定元素在数组中没有出现......");
} else {
System.out.println("指定元素在数组中出现的第一次索引是:" + index);
}
}
public static int getIndex(int[] arr, int num) {
//声明并初始化索引变量
int index = -1;
//进行数组的非空校验
if (arr == null) {
return index;
}
//声明并初始化指定的索引范围变量
int start = 0;
int end = arr.length - 1;
//声明并初始化中间索引位置变量
int mid = (start + end)/2;
//考虑到不太清楚循环次数,选择while循环
while (start <= end) {
if (arr[mid] < num) {
start = mid + 1;
//mid = (start + end) / 2;
} else if (arr[mid] > num) {
end = mid - 1;
//mid = (start + end) / 2;
} else {
index = mid;
break;
}
mid = (start + end) / 2;
}
return index;
}
数组的动态 *** 作:
数组的动态扩容:
创建新数组,进行数组的复制将待添加的元素存储到新数组中的最后
数组的动态插入:
创建新数组,根据指定的索引位置将待添加的元素存储到该新数组中
数组的动态删除:
创建新数组,根据指定的索引位置复制数组中的元素
数组的动态扩容
public static void main(String[] args) {
//声明并初始化数组
int[] arr = {11,22,33,44,55};
//声明并初始化待添加元素
int num = 66;
System.out.println("数组动态扩容前:");
print(arr);
//进行动态扩容
arr = add(arr, num);
System.out.println("数组动态扩容后:");
print(arr);
}
/*
动态扩容的两个明确:
返回类型:int[]
形参列表:int[] oldArr,int num
*/
public static int[] add (int[] oldArr , int num) {
//非空校验
if (oldArr == null) {
return oldArr;
}
//根据原来的数组创建新数组
int[] newArr = new int[oldArr.length + 1];
//进行数据复制
for (int i = 0; i < oldArr.length; i++) {
newArr[i] = oldArr[i];
}
//将待添加元素存储到新数组的最后
newArr[newArr.length - 1] = num;
//返回新数组
return newArr;
}
public static void print (int[] arr) {
//非空校验
if (arr == null) {
return;
}
//特殊实参判断
if (arr.length == 0) {
System.out.println("[]");
return;
}
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
System.out.println(arr[i] + "]");
} else {
System.out.print(arr[i] + ", ");
}
}
}
数组的动态插入
public static void main(String[] args) {
//声明并初始化数组
int[] arr = {11,22,33,44,55};
//声明并初始化待插入元素
int num = 66;
System.out.println("数组动态插入前:");
print(arr);
//进行动态插入
arr = insert(arr,num,1);
System.out.println("数组动态插入后:");
print(arr);
}
/*
动态插入的两个明确:
返回类型:int[]
形参列表:int[] oldArr,int num,int index
*/
public static int[] insert (int[] oldArr,int num,int index) {
//非空校验
if (oldArr == null) {
return oldArr;
}
//非法索引判断
if (index < 0 || index >= oldArr.length) {
return oldArr;
}
//根据原来的数组创建新数组
int[] newArr = new int[oldArr.length + 1];
//进行数据的复制
for (int i = 0; i < oldArr.length; i++) {
if (i < index) {
newArr[i] = oldArr[i];
} else {
newArr[i+1] = oldArr[i];
}
}
//将待插入元素存储到index位置上
newArr[index] = num;
return newArr;
}
public static void print (int[] arr) {
//非空校验
if (arr == null) {
return;
}
//特殊实参判断
if (arr.length == 0) {
System.out.println("[]");
return;
}
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
System.out.println(arr[i] + "]");
} else {
System.out.print(arr[i] + ", ");
}
}
}
数组的动态删除
public static void main(String[] args) {
//声明并初始化数组
int[] arr = {11,22,33,44,55};
System.out.println("数组动态删除前:");
print(arr);
//进行动态删除
arr = remove(arr,2);
System.out.println("数组动态删除后:");
print(arr);
}
/*
动态删除的两个明确:
返回类型:int[]
形参列表:int[] oldArr,int index
*/
public static int[] remove (int[] oldArr,int index) {
//非空校验
if (oldArr == null) {
return oldArr;
}
//非法索引判断
if (index < 0 || index >= oldArr.length) {
return oldArr;
}
//根据原来数组创建新数组
int[] newArr = new int[oldArr.length - 1];
//数组元素的复制
for (int i = 0; i < newArr.length; i++) {
if (i < index) {
newArr[i] = oldArr[i];
} else {
newArr[i] = oldArr[i+1];
}
}
//返回新数组
return newArr;
}
public static void print (int[] arr) {
//非空校验
if (arr == null) {
return;
}
//特殊实参判断
if (arr.length == 0) {
System.out.println("[]");
return;
}
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
System.out.println(arr[i] + "]");
} else {
System.out.print(arr[i] + ", ");
}
}
}
多维数组
含义:
数组中的元素依然是数组的数组
分类:
一维数组(我们之前学习的就是一维数组,多维数组中不包含一维数组)
二维数组
三维数组
......
二维数组的声明:
数据类型[][] 数组名;(推荐)
数据类型 数组名[][];
数据类型[] 数组名[];
二维数组的初始化:
动态初始化:
格式1:初始化二维数组长度的同时,也初始化里面每个一维数组的长度
数据类型[][] 数组名 = new 数据类型[x][y];
x:二维数组的长度,也就是包含几个一维数组
y:二维数组中每个一维数组的长度
格式2:只初始化二维数组长度,但不会初始化里面每个一维数组的长度
数据类型[][] 数组名 = new 数据类型[x][];
静态初始化:
格式1:
数据类型[][] 数组名 = new 数据类型[][]{new 数据类型[]{元素1,元素2,......,元素n},new 数据类型[]{元素1,元素2,......,元素n},......,new 数据类型[]{元素1,元素2,......,元素n}}
格式2:
数据类型[][] 数组名 = {new 数据类型[]{元素1,元素2,......,元素n},new 数据类型[]{元素1,元素2,......,元素n},......,new 数据类型[]{元素1,元素2,......,元素n}}
格式3:
数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2,......,元素n},{元素1,元素2,......,元素n},......,{元素1,元素2,......,元素n}}
格式4:
数据类型[][] 数组名 = {{元素1,元素2,......,元素n},{元素1,元素2,......,元素n},......,{元素1,元素2,......,元素n}}
//数据类型[][] 数组名 = new 数据类型[x][y];
int[][] arr01 = new int[3][2];
System.out.println(arr01);
System.out.println(arr01[0]);
System.out.println(arr01[1]);
System.out.println(arr01[2]);
//数据类型[][] 数组名 = new 数据类型[x][];
int[][] arr02 = new int[3][];
System.out.println(arr02);
System.out.println(arr02[0]);
System.out.println(arr02[1]);
System.out.println(arr02[2]);
//数据类型[][] 数组名 = new 数据类型[][]{new 数据类型[]{元素1,元素2,......,元素n},new 数据类型[]{元素1,元素2,......,元素n},......,new 数据类型[]{元素1,元素2,......,元素n}}
int[][] arr03 = new int[][]{new int[]{11,22,33},new int[]{44,55},new int[]{66,77,88,99}};
//数据类型[][] 数组名 = {new 数据类型[]{元素1,元素2,......,元素n},new 数据类型[]{元素1,元素2,......,元素n},......,new 数据类型[]{元素1,元素2,......,元素n}}
int[][] arr04 = {new int[]{11,22,33},new int[]{44,55},new int[]{66,77,88,99}};
//数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2,......,元素n},{元素1,元素2,......,元素n},......,{元素1,元素2,......,元素n}}
int[][] arr05 = new int[][]{{11,22,33},{44,55},{66,77,88,99}};
//数据类型[][] 数组名 = {{元素1,元素2,......,元素n},{元素1,元素2,......,元素n},......,{元素1,元素2,......,元素n}}
int[][] arr06 = {{11,22,33},{44,55},{66,77,88,99}};
二维数组的元素访问
格式:
数组名[x][y]
x:访问元素所在一维数组在二维数组中的索引
y:访问元素在一维数组中的索引
int[][] arr = {{11,22,33},{44,55},{66,77,88,99}};
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[0][0]);
System.out.println(arr[0][1]);
System.out.println(arr[0][2]);
System.out.println(arr[1]);
System.out.println(arr[1][0]);
System.out.println(arr[1][1]);
System.out.println(arr[2]);
System.out.println(arr[2][0]);
System.out.println(arr[2][1]);
System.out.println(arr[2][2]);
System.out.println(arr[2][3]);
二维数组的遍历
int[][] arr = {{11,22,33},{44,55},{66,77,88,99}};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.println(arr[i][j]);
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)