数组知识点整理 【最详细 最全面 持续更新中...】
数组
你好! 本章主要整理数组相关的知识点。如果你想要掌握数组基本语法知识或者更好地了解数组, 可以仔细阅读这篇文章。
1.数组的引入
场景引入: Java考试结束后,老师给老王分配了一项任务,让他计算全班(300人)的平均分。
解决方法:定义三百个变量,然后相加求和,并计算平均分。
技术缺陷:重复定义变量
可以使用数组来改进程序,如下程序所示:
/**
* 需求: 计算全班(300个人)的平均分。
* @author Xyr
*/
public class MyArray {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// 定义数组
double[] scores = new double[30];
double sum = 0.0;
double average = 0.0;
for (int i = 0; i < scores.length; i++) {
System.out.print("请输入第" + (i+1) + "个学生的成绩:");
scores[i] = input.nextDouble();
// 累加求和
sum += scores[i];
}
average = sum / scores.length;
System.out.println(scores.length + "个学生的平均成绩是:" + average);
input.close();
}
}
2.数组的概念
数组是用于存放一组相同数据类型变量的数组容器。
数组的特点:
1.数组本质是一个引用类型的变量,既然是变量就必须先声明再赋值再使用
2.数组元素类型在编译时期就确定下来,只能够存储相同数据类型的一组数据
3.数组会在堆区创建一组连续的内存空间,数组首地址作为数组的内存地址
3.数组的初始化
静态初始化: 初始化的同时为每一个元素给出初始值,不需要指定数组的长度,系统会根据元素的个数去动态计算数组的长度。
格式一: 数据类型[] 数组名 = {元素1,元素2,元素3,...元素n};
格式二: 数据类型[] 数组名 = new int[]{元素1,元素2,元素3,...元素n};
动态初始化: 系统来为数组赋初始值,但是必须由我们指定数组的长度.
默认值规则如下
byte short int long 默认值 0
float double 默认值 0.0
char 默认值 '\u0000' 就是一个空字符
boolean 默认值 false
引用类型 默认值 null
/*
* 数组的初始化
* 静态初始化
* 格式一: 数据类型[] 数组名 = {元素1,元素2,元素3,元素4,元素5,...元素n};
* 格式二: 数据类型[] 数组名 = new int[]{元素1,元素2,元素3,元素4,元素5,...元素n};
* 动态初始化
* 数据类型[] 数组名 = new 数据类型[数组的大小];
* 可以采用以下三种方式初始化
* 1.逐个初始化
* 2.通过键盘输入
* 3.通过随机数初始化
*
* 静态初始化和动态初始化的区别?
* 静态初始化: 初始化的同时为每一个元素给出初始值,不需要指定数组的长度,系统会根据元素的个数去动态计算数组的长度
* 动态初始化: 初始化的系统来为数组赋初始值,默认值是堆区的特点的默认值,但是必须由我们指定数组的长度
*/
public class ArrayDemo02 {
public static void main(String[] args) {
// 动态初始化
// 1.逐个初始化
int[] arr = new int[3];
String[] names = new String[3];
names[0] = "张三1";
names[1] = "张三2";
names[2] = "张三3";
arr[0] = 100;
arr[1] = 200;
arr[2] = 300;
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
// 2.通过键盘输入
Scanner input = new Scanner(System.in);
for (int i = 0; i < arr.length; i++) {
System.out.print("请输入第" + (i + 1) + "个元素: ");
arr[i] = input.nextInt();
}
System.out.println(Arrays.toString(arr));
// 3.通过随机数初始化
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 10);
}
System.out.println(Arrays.toString(arr));
// 数据类型[] 数组名 = {元素1,元素2,元素3,元素4,元素5,...元素n};
int[] arr2 = { 11, 22, 33 };
System.out.println(Arrays.toString(arr2));
// 格式二: 数据类型[] 数组名 = new int[]{元素1,元素2,元素3,元素4,元素5,...元素n};
int[] arr3 = new int[] { 11, 22, 33, 44, 55, 66 };
System.out.println(Arrays.toString(arr3));
// 有了方式一为什么需要有方式二?
// int[] arr4;
// arr4 = {11, 22, 33, 44, 55}; 这样初始化编译报错,不能使用方式一
int[] arr4;
arr4 = new int[] { 11, 22, 33, 44, 55, 66 };
System.out.println(Arrays.toString(arr4));
// 后面面向对象会学习匿名对象,需要使用方式二
Arrays.toString(new int[] { 11, 22, 33, 44, 55, 66 });
}
}
4.数组注意事项
public class ArrayDemo01 {
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr); // [I@7852e922
System.out.println(arr[0]); // 0
System.out.println(arr[1]); // 0
System.out.println(arr[2]); // 0
System.out.println(arr[-3]); // java.lang.ArrayIndexOutOfBoundsException: 3
int[] arr2 = null;
System.out.println(arr2[1]); // java.lang.NullPointerException
}
}
内存图如下所示:
异常解析:
/*
* java.lang.ArrayIndexOutOfBoundsException: 3
* 异常名称: 数组越界
* 产生原因: 访问数组的下标不在 0~数组的长度-1之间
* 解决办法: 检查范围
*
* java.lang.NullPointerException
* 异常名称: 空指针异常
* 产生原因: 对象没有new,就访问对象成员
* 解决办法: 找对null值对象并且创建对象
* /
5.数组的遍历
public class ArrayDemo03 {
public static void main(String[] args) {
int[] arr = { 11, 22, 33, 44, 55 };
// 方式一
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
System.out.println(arr[5]);
// 方式二
for (int i = 0; i < 6; i++) {
System.out.println(arr[i]);
}
// 数组只有一个属性: length 数组的长度
System.out.println(arr.length);
// 方式二: 数组长度属性改进
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
// 方式三: 方法改进
printArr(arr);
System.out.println(arrayToString(arr));
// 系统提供了一个工具类方便我们遍历数组 Arrays
System.out.println(Arrays.toString(arr));
}
public static void printArr(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
// 打印格式:[11, 22, 33, 44, 55]
public static String arrayToString(int[] arr) {
String result = "";
result += "[";
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
// 如果是最后一个元素,拼接数据
result += arr[i];
} else {
// 如果是最后一个元素,拼接数据+,_
result += arr[i] + ", ";
}
}
result += "]";
return result;
}
// 源码 Arrays工具类是如何重写 toString 方法的,我们可以参考学习
public static String toString(int[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
}
6.数组中关于值传递和引用传递问题
/*
* 当形式参数是引用类型的时候的传递过程
*
* 八大基本类型传递满足类型转换
* 引用类型
* 数组
* 类
* 接口
*
* 值传递和引用传递
* 1.值传递的本质传递的是数值本身,引用传递的本质传递的是地址
* 2.如果传递的是地址,那么通过地址改变了堆区空间的数值,将会影响到所有指向该堆区的引用
*/
public class ArrayDemo04 {
public static void main(String[] args) {
int a = 10;
System.out.println("方法调用前参数a的值: " + a); // 10
change(a);
System.out.println("方法调用后参数a的值: " + a); // 10
int[] arr = {11, 22, 33};
System.out.println("方法调用前数组的所有元素的值: " + Arrays.toString(arr)); // [11, 22, 33]
change(arr);
System.out.println("方法调用后数组的所有元素的值: " + Arrays.toString(arr)); // [11, 300, 22]
}
public static void change(int a) {
a += 5;
System.out.println("方法中的参数a的值: " + a); // 15
}
public static void change(int[] arr) {
arr[1] = 300;
System.out.println("方法中数组的所有元素的值: " + Arrays.toString(arr)); // [11, 300, 33]
}
}
值传递内存图如下所示:
引用传递内存图如下所示:
地址传递小案例:
import java.util.Arrays;
public class ArrayDemo {
public static void main(String[] args) {
int[] arr = {11, 22, 33}; // [11, 200, 33]
int[] arr2 = {44, 55, 66}; // [44, 55, 66]
arr[1] = 200;
int[] arr3 = arr; // [11, 200, 33]
System.out.println(Arrays.toString(arr)); // [11, 200, 33]
System.out.println(Arrays.toString(arr2)); // [44, 55, 66]
System.out.println(Arrays.toString(arr3)); // [11, 200, 33]
arr3[2] = 400;
System.out.println(Arrays.toString(arr)); // [11, 200, 400]
System.out.println(Arrays.toString(arr2)); // [44, 55, 66]
System.out.println(Arrays.toString(arr3)); // [11, 200, 400]
}
}
7.数组中常见的思想
7.1 遍历思想
/*
* 功能: 将数组中的元素转换成字符串
* 返回值类型: String
* 参数列表: int[] arr
* 方法名: arrayToString
*/
public static String arrayToString(int[] arr) {
String result = "";
result += "[";
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
// 如果是最后一个元素,拼接数据
result += arr[i];
} else {
// 如果是最后一个元素,拼接数据+,_
result += arr[i] + ", ";
}
}
result += "]";
return result;
}
7.2 求和思想
1.定义求和变量
2.累加求和
/*
* 功能:求数列中所有数值的和。
* 返回值类型: int
* 参数列表: int[] arr
* 方法名: getSum
*/
public static int getSum(int[] arr) {
// 1.定义求和变量
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
7.3 最值思想
1.假设第一个数是最大值
2.遍历数组中的每一个元素,获取到每一个元素
3.如果遍历的元素比假定的最大值还要大
4.就设置这个元素为最大值
5.循环结束之后,就获取到了最大值
/*
* 功能: 求出最大值。
* 返回值类型: int
* 参数列表: int[] arr
* 方法名: getMaxValue
*/
public static int getMaxValue(int[] arr) {
// 1.假设第一个数为最大值
int max = arr[0];
// 2.遍历数组中的每一个元素
for (int i = 0; i < arr.length; i++) {
// 获取到每一个元素arr[i]
// 3.判断获取的元素是否比max大
if (arr[i] > max) {
// 4.设置arr[i]为最大值
max = arr[i];
}
}
return max;
}
/*
* 功能: 求出最小值。
* 返回值类型: int
* 参数列表: int[] arr
* 方法名: getMinValue
*/
public static int getMinValue(int[] arr) {
// 1.假设第一个数为最大值
int min = arr[0];
// 2.遍历数组中的每一个元素
for (int i = 0; i < arr.length; i++) {
// 获取到每一个元素arr[i]
// 3.判断获取的元素是否比max大
if (arr[i] < min) {
// 4.设置arr[i]为最大值
min = arr[i];
}
}
return min;
}
最值思想原理图如下所示:
7.4 倒置思想
/*
* 功能: 将数组倒置并输出
* 返回值类型: void
* 参数列表: int[] arr
* 方法名: reverseArray
*
* {8,4,2,1,23,344,12} --> {12,344,23,1,2,4,8}
* 第一交换
* 第一个数和最后一个数交换位置
* int temp = 0;
* temp = arr[0];
* arr[0] = arr[arr.length - 1 - 0];
* arr[arr.length - 1 - 0] = temp;
*
* 第二次交换
* 第二个数和倒数第二个数交换位置
* int temp = 0;
* temp = arr[1];
* arr[1] = arr[arr.length - 1 - 1];
* arr[arr.length - 1 - 1] = temp;
*
* 第三次交换
* 第三个数和倒数第三个数交换位置
* int temp = 0;
* temp = arr[2];
* arr[2] = arr[arr.length - 1 - 2];
* arr[arr.length - 1 - 2] = temp;
*
* 循环体代码:
* int temp = 0;
* tmep = arr[i];
* arr[i] = arr[arr.length - 1 - i];
* arr[arr.length - 1 - i] = temp;
*
* 循环的次数
* 7个数 --> 交换3次
* 6个数 --> 交换3次
* 5个数 --> 交换2次
* 4个数 --> 交换2次
* i个数 --> 交换i/2次
*/
public static void reverseArray(int[] arr) {
for (int i = 0; i < arr.length / 2; i++) {
int temp = 0;
temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
}
7.5 排序思想
1.冒泡排序法
import java.util.Arrays;
/*
* 冒泡排序法
* 1.相邻两个数进行比较,大的数往后冒泡,第一趟比较完毕,最大值就出现在了最大索引处
* 2.一共比较了arr.length - 1趟
* 3.每一趟比上一趟比较少一次
*/
public class ArrayDemo07 {
public static void main(String[] args) {
int[] arr = {24, 69, 80, 55, 13};
System.out.println("排序前: " + Arrays.toString(arr));
// for (int i = 0; i < arr.length - 1 - 0; i++) {
// /*
// * arr[0] arr[1]比较
// * arr[1] arr[2]比较
// * arr[2] arr[3]比较
// * arr[3] arr[4]比较
// */
// if (arr[i] > arr[i + 1]) {
// int temp = 0;
// temp = arr[i];
// arr[i] = arr[i+1];
// arr[i+1] = temp;
// }
// }
// System.out.println("第一趟排序后: " + Arrays.toString(arr));
//
// for (int i = 0; i < arr.length - 1 - 1; i++) {
// /*
// * arr[0] arr[1]比较
// * arr[1] arr[2]比较
// * arr[2] arr[3]比较
// */
// if (arr[i] > arr[i + 1]) {
// int temp = 0;
// temp = arr[i];
// arr[i] = arr[i+1];
// arr[i+1] = temp;
// }
// }
// System.out.println("第二趟排序后: " + Arrays.toString(arr));
//
// for (int i = 0; i < arr.length - 1 - 2; i++) {
// /*
// * arr[0] arr[1]比较
// * arr[1] arr[2]比较
// */
// if (arr[i] > arr[i + 1]) {
// int temp = 0;
// temp = arr[i];
// arr[i] = arr[i+1];
// arr[i+1] = temp;
// }
// }
// System.out.println("第三趟排序后: " + Arrays.toString(arr));
//
// for (int i = 0; i < arr.length - 1 - 3; i++) {
// /*
// * arr[0] arr[1]比较
// */
// if (arr[i] > arr[i + 1]) {
// int temp = 0;
// temp = arr[i];
// arr[i] = arr[i+1];
// arr[i+1] = temp;
// }
// }
// System.out.println("第四趟排序后: " + Arrays.toString(arr));
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = 0;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println("排序后: " + Arrays.toString(arr));
}
}
原理示意图:
2. 选择排序法
/*
* 选择排序法
* 选择排序法原理
* 1.每一个元素依次和后面所有的元素比较,每一趟比较完毕,最小的数就出现在了最小索引处
* 2.一共比较了arr.length-1趟
* 3.每一趟上一趟少比较1次
*/
public class ArrayDemo10 {
public static void main(String[] args) {
int[] arr = {44, 89, 100, 73, 33};
System.out.println("排序前: " + Arrays.toString(arr));
/*int i = 0;
for (int j = i+1; j < arr.length; j++) {
if (arr[j] < arr[i]) {
int temp = 0;
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
System.out.println("第一趟排序后: " + Arrays.toString(arr));
i = 1;
for (int j = i+1; j < arr.length; j++) {
if (arr[j] < arr[i]) {
int temp = 0;
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
System.out.println("第二趟排序后: " + Arrays.toString(arr));
i = 2;
for (int j = i+1; j < arr.length; j++) {
if (arr[j] < arr[i]) {
int temp = 0;
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
System.out.println("第三趟排序后: " + Arrays.toString(arr));
i = 3;
for (int j = i+1; j < arr.length; j++) {
if (arr[j] < arr[i]) {
int temp = 0;
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
System.out.println("第四趟排序后: " + Arrays.toString(arr));*/
/*for (int i = 0; i < arr.length - 1; i++) {
for (int j = i+1; j < arr.length; j++) {
if (arr[j] < arr[i]) {
int temp = 0;
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}*/
selectSort(arr);
System.out.println("选择排序后: " + Arrays.toString(arr));
}
public static void selectSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i+1; j < arr.length; j++) {
if (arr[j] < arr[i]) {
int temp = 0;
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
}
}
排序原理图如下所示:
7.6 查找思想
- 基本查找
/*
* 数组查找:从键盘中任意输入一个数据,判断数列中是否包含此数。
* 返回值类型: boolean
* 参数列表: int[] arr, int num
* 方法名: isContainsNum
*/
public static boolean isContainsNum(int[] arr, int num) {
// 默认概述在数组中不存在
boolean flag = false;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == num) {
flag = true;
break;
}
}
return flag;
}
/*
* 数组查找:从键盘中任意输入一个数据,判断数列中是否包含此数。
* 返回值类型: int
* 参数列表: int[] arr, int num
* 方法名: baiscSearch
*/
public static int baiscSearch(int[] arr, int num) {
int index = -1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == num) {
index = i;
break;
}
}
return index;
}
- 二分法查找/折半查找
/*
* 二分查找/折半查找: 该种查找方式仅限于有序的元素进行查找
*
* 如果一个数组是无序的,只能够使用基本查找,如果是有序的,可以考虑使用二分法查找
* 当然就算是无序,我们可以使用快速排序法先排序再查找
*/
public class ArrayDemo05 {
public static void main(String[] args) {
int[] arr = {11, 22, 33, 44, 55, 66, 77};
// System.out.println(binarySearch(arr, 99));
System.out.println(Arrays.binarySearch(arr, 65));
}
public static int binarySearch(int[] arr, int num) {
// 1.定义最大索引和最小索引
int max = arr.length - 1;
int min = 0;
// 2.计算中间索引
int mid = (max + min) / 2;
// 3.拿中间索引所对应的值和需要查找的数进行比较,通过循环比较
while(arr[mid] != num) {
/*
* 大了,往左边找
* 小了,往右边找
*/
if (arr[mid] > num) {
max = mid - 1;
} else if (arr[mid] < num) {
min = mid + 1;
}
if (min > max) {
return -1;
}
mid = (min + max) / 2;
}
// 返回中间索引
return mid;
}
}
折半查找原理图如下所示:
8.foreach遍历数组
/*
* foreach遍历
*
* 概念:集合和数组专有的遍历方式
*
* 语法格式:
* for(元素类型 元素变量名 : 数组/集合){
* 通过元素变量名来操作每一个元素;
* }
*
* foreach遍历方式的特点:
* 1.简化了遍历
* 2.foreach没有索引
* 3.foreach底层还是使用了普通for遍历
*
* 编译时期系统会读取foreach的格式,转化普通for格式
* int ai[];
* int k = (ai = arr).length;
* for (int j = 0; j < k; j++)
* {
* int = ai[j];
* System.out.println(i);
* }
*/
public class ArrayDemo01 {
public static void main(String[] args) {
int[] arr = {11, 22, 33, 44, 55};
for(int i : arr) {
System.out.println(i);
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
9.可变参数
/*
* 可变参数
* 为什么需要学习可变参数?
* 当参数的类型相同,但是参数的个数不同,我们会出现代码复制,可以考虑可变参数改进
*
* 可变参数的格式
* 参数类型... 形参变量名
*
* 可变参数的特点:
* 1.可变参数本质是数组,我们完全可以像使用数组一样使用可变参数。
* 2. ...的位置只能够放置在参数类型和变量名之间。
* 3.如果形参列表中出现可变参数,那么可变参数必须出现在参数列表的最后面。
*/
public class ArrayDemo02 {
public static void main(String[] args) {
System.out.println(add(10, 20));
System.out.println(add(10, 20, 30));
System.out.println("====================");
System.out.println(add(10, 20, 30, 40));
}
// 计算两个数的和
// public static int add(int a, int b) {
// return a + b;
// }
// 计算三个数的和
// public static int add(int a, int b, int c) {
// return a + b + c;
// }
// arguments 参数
public static int add(int... args) {
// System.out.println(args); // [I@7852e922
int sum = 0;
for (int i : args) {
sum += i;
}
return sum;
}
public static int add(double d, int... args) {
// System.out.println(args); // [I@7852e922
int sum = 0;
for (int i : args) {
sum += i;
}
return sum;
}
}
10.Arrays工具类
import java.util.Arrays;
/*
* Arrays工具类
*
* public static native void arraycopy(Object src, int srcPos,Object dest, int destPos, int length);
*/
public class ArrayDemo03 {
public static void main(String[] args) {
int[] arr = {22, 11, 66, 88, 99, 44};
// Arrays的遍历输出方法
System.out.println(Arrays.toString(arr));
// Arrays的排序方法
// Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
// Arrays的二分法查找方法
int index = Arrays.binarySearch(arr, 88);
System.out.println(index);
// System的arraycopy方法,这是一个本地方法,底层不由Java实现,由C语言实现
int[] dest = {100, 200, 300};
// Object src, int srcPos,Object dest, int destPos, int length
System.arraycopy(arr, 1, dest, 0 ,3);
System.out.println(Arrays.toString(dest));
// 复制数组
int[] newArr = Arrays.copyOf(arr, arr.length);
System.out.println(Arrays.toString(newArr));
// 数组扩容
int[] newArr2 = Arrays.copyOf(arr, arr.length + 1);
System.out.println(Arrays.toString(newArr2));
// 缩小数组的容量
int[] newArr3 = Arrays.copyOf(arr, arr.length - 2);
System.out.println(Arrays.toString(newArr3));
// 填充数组
// Arrays.fill(arr, 100);
// System.out.println(Arrays.toString(arr));
// 填充数组的一部分 左闭右开原则
// Arrays.fill(arr, 2, 4, 100);
// System.out.println(Arrays.toString(arr));
int[] copyArr = Arrays.copyOfRange(arr, 2, 5);
System.out.println(Arrays.toString(copyArr));
int[] arr1 = {11, 22, 33, 44};
int[] arr2 = {11, 22, 33, 44};
System.out.println(Arrays.equals(arr1, arr2));
}
}
11.动态扩容
/*
* 数组的扩容和缩容
* 动态扩容
* 1.使用for循环复制元素扩容
* 缺陷: 拷贝一部分元素需要计算索引,比较复杂
* 2.System.arracopy()扩容
* 缺陷: 拷贝数组的一部分到目标数组,如果长度超过了目标数组的索引,会抛出异常
* 3.Arrays.copyOf扩容
* 观察copyOf方法的源码:
* public static int[] copyOf(int[] original, int newLength) {
* int[] copy = new int[newLength];
* System.arraycopy(original, 0, copy, 0,
* Math.min(original.length, newLength));
* return copy;
* }
* 4.利用Object类中一个 clone 方法,该方法是真正意义上的复制数组
*/
public class ArrayDemo04 {
public static void main(String[] args) {
int[] src = { 11, 22, 33, 44 };
int[] desc = new int[10];
// 1.使用for循环复制元素扩容
// for (int i = 0; i < src.length; i++) {
// desc[i] = src[i];
// }
// System.out.println(Arrays.toString(desc));
// 2.System.arracopy()扩容
// System.arraycopy(src, 0, desc, 7, src.length); // 数组越界
// System.out.println(Arrays.toString(desc));
// 3.Arrays.copyOf扩容
int[] descArr = Arrays.copyOf(src, src.length + 5);
System.out.println(Arrays.toString(descArr));
}
}
12.数组实现增删查改操作
package com.sxt.arraydemo;
import java.util.Arrays;
/*
* 数组的 基本操作 【增删查改】
* 其实数组也是一种数据结构
* 特点:
* 1.有索引
* 2.查询和修改效率高,方便
* 3.增加和删除的效率低
*/
public class ArrayDemo05 {
static int[] srcArr;
public static void main(String[] args) {
srcArr = new int[] {11, 22, 33, 44};
System.out.println(Arrays.toString(srcArr));
add(55);
System.out.println(Arrays.toString(srcArr));
add(66);
System.out.println(Arrays.toString(srcArr));
insert(srcArr.length, 100);
System.out.println(Arrays.toString(srcArr));
remove(6);
System.out.println(Arrays.toString(srcArr));
System.out.println(get(0));
set(1, 200);
System.out.println(Arrays.toString(srcArr));
}
/*
* 动态扩容的原理
* 往数组中动态添加一个元素
* 返回值类型: void
* 参数列表: int num
* 方法名: add
*/
/*public static void add(int num) {
// 利用System.arraycopy方法处理
int[] descArr = new int[srcArr.length + 1];
// 复制数组
System.arraycopy(srcArr, 0, descArr, 0, srcArr.length);
// 将num赋值到目标数组的最后一个位置
descArr[descArr.length - 1] = num;
// 地址传递
srcArr = descArr;
}*/
public static void add(int num) {
int[] descArr = Arrays.copyOf(srcArr, srcArr.length + 1);
descArr[descArr.length - 1] = num;
srcArr = descArr;
}
/*
* 往数组的任意位置插入一个元素
* 返回值类型: void
* 参数列表: int index, int num
* 方法名: insert
*/
public static void insert(int index, int num) {
int[] descArr = new int[srcArr.length + 1];
System.arraycopy(srcArr, 0, descArr, 0, index);
descArr[index] = num;
System.arraycopy(srcArr, index, descArr, index + 1, srcArr.length - index);
srcArr = descArr;
}
/*
* 将数组中的某个索引处的元素删除
* 返回值类型: void
* 参数列表: int index
* 方法名: remove
*/
public static void remove(int index) {
int[] descArr = new int[srcArr.length - 1];
System.arraycopy(srcArr, 0, descArr, 0, index);
System.arraycopy(srcArr, index + 1, descArr, index, descArr.length - index);
srcArr = descArr;
}
public static int get(int index) {
return srcArr[index];
}
public static void set(int index, int num) {
srcArr[index] = num;
}
}
13.二维数组的概念和格式
/*
* 多维数组本质也是一维数组
* 二维数组
* 本质就是存放了一维数组的数组
*
* 格式1:
* 数据类型[] 数组名 = new 数据类型[数组的长度];
* 数据类型[][] 数组名 = new 数据类型[m][n];
* m: 二维数组中一维数组的长度
* n: 每一个一维数组中元素的个数
*
* int[][] arr = new int[3][2];
* 表示arr中有3个一维数组,每一个一维数组有2个元素
*
* 变式:
* 数据类型 数组名[][] = new 数据类型[m][n];
* 数据类型[] 数组名[] = new 数据类型[m][n];
*
* 面试题:
* int[] x,y[],z[][]; 表示1个一维数组,1一个二维数组,1个三维数组
*
* int[] x;
* int[] y[];
* int[] z[][];
*
* 格式2:
* 数组类型[][] 数组名 = new 数据类型[m][];
* m: 二维数组中一维数组的长度
* n: m必不可少,n可省略,表示每一个一维数组的元素个数不确定
* 可以后期动态地改变每一个一维数组元素的个数
*
* int a=2,b=2,c;
*/
public class TwoArrayDemo01 {
public static void main(String[] args) {
int[][] arr = new int[3][2];
int[] arr2[] = new int[3][3];
int[] x,y[],z[][]; // 1
int n[] = new int[2],i,j,k;
/*
* int n[] = new int[2];
* int i;
* int j;
* int k;
*/
}
}
14.二维数组的内存分析
格式一的内存图
格式一: 数据类型[][] 数组名 = new 数据类型[m][n];
格式二的内存图
格式二: 数据类型[][] 数组名 = new 数据类型[m][];