9.数组与可变参数
2075字约7分钟
2024-12-02
一维数组
数组可以存放多个同一类型的数据,数组也是一种数据类型,是应用类型的,数组就是一组数据
静态分配
int[] arr = {1, 2, 3};
动态分配
int[] arr = new int[3];
一维数组的赋值机制
基本数据类型的赋值是 值拷贝(也可以叫值传递)
数组的赋值是 地址拷贝(也叫引用传递)
int[] arr = {1, 2, 3};
// 一个数组赋值到另一个数组中,修改其中一个数组中的任意一个元素值,都会影响到另一个数组中的元素值
int[] arr1 = arr;
// arr1中第一个元素值从1修改为10,arr中的第一个元素也会从1变成10
arr1[0] = 10;
一维数组的拷贝
int[] arr = {1, 2, 3};
int[] arr1 = new int[arr.length];
// 像这样一个元素一个元素的拷贝的这种,才是真正意义上的拷贝
// 这样修改arr1中的元素则不会影响到arr中的元素
for (int i = 0; i < arr1.length; i++) {
arr1[i] = arr[i];
}
二维数组
静态分配
int[][] arr = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
动态分配
int[][] arr = new int[3][3];
二维数组的赋值机制
和一维数组一样,一个数组赋值到另一个数组,修改其中一个数组中的元素值则另一个数组中的元素值也会受到影响
int[][] arr = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int[][] arr1 = arr;
arr1[0][0] = 10;
二维数组的拷贝
和一维数组一样,这样一个一个的拷贝,才是真正意义上的拷贝,修改其中一个数组中的元素值不会影响到另一个数组中的元素值
int[][] arr = {{1, 2, 3}, {4, 5, 6}};
int[][] arr1 = new int[arr.length][3];
for (int i = 0; i < arr1.length; i++) {
for (int j = 0l j < arr[i].length; j++) {
arr1[i][j] = arr[i][j];
}
}
数组扩容
// 原数组
int[] arr = {1, 2, 3};
// 扩容数
int addNum = 2;
// 扩容两个元素,说白了就是创建新的数组,然后再将老数组赋值到新数组里面
int[] addArr = new int[arr.length + addNum];
for (int i = 0; i < add.length; i++) {
addArr[i] = add[i];
}
// 给新数组添加新元素
for (int i = 0; i < addNum; i++) {
addArr[arr.length + i] = myScanner.nextInt();
}
// 最后让老数组指向新数组
arr = addArr;
在数组中添加元素,并保持有序
题目:已知一个升序数组,然后在这个数组中插入一个元素要求:插入元素之后该数组还是升序数组,该数组还是由小到大的顺序排列
// 默认数组
int[] arr = {10, 20, 30, 40, 50};
// 创建一个新数组,将老数组赋值到该新数组中
int[] arr1 = new int[arr.length + 1];
// 插入的元素
int a = 1;
// 这里的b之所以不为0,是因为这里的b所对应的是下标的值,而下标的值最小值就是0
// 所以为了避免冲突,就设置为负数
int b = -1;
// 找到合适的下标位置
for (int i = 0; i < arr.length; i++) {
if (a < arr[i]) {
b = i;
break;
}
}
// 插入的数大于原数组中的所有元素时,下标则为原数组的最大值
if (b == -1) {
// 下标则为最大值
b = arr1.length - 1;
}
// i 所对应的是数组arr1的下标,j 所对应的是数组arr的下标
for (int i = 0, j = 0; i < arr1.length; i++) {
if (i == b) {
// 当循环到 比 插入的元素 大的 元素所对应的下标下时
// 把插入的元素赋值给当前下标
arr1[b] = a;
} else {
// 当数组arr赋值给数组arr1时,数组arr元素所对应的下标则自增
arr1[i] = arr[j];
j++;
}
}
数组的注意事项
数组与数组之间是不能进行比较的,但是数组中的元素可以
// 下面这两行代码的区别是 new int[3] 表示的是创建 3 个int类型
int[] arr = new int[3];
// 而下面这行代码表示的是 arr这个数组中的第 3 个元素,其中 arr[2] 表示的是下标的意思
// arr[2] = 1; 表示的是把 1 赋值给 arr 这个数组中的第 3 个元素
arr[2] = 1;
int[][] arr2 = new int[3][];
// 输出的值是 null,因为数组arr2只有元素个数,但是每个元素中的元素并没有定义,所以为空
System.out.println(arr2[2]);
// 如果 new int[1]; 表示创建一个元素,中括号里面不能没有值,否则会报错
int[] arr3 = new int[1];
// 输出的值是 0,因为 int 类型的数组的默认值是 0
System.out.println(arr3[0]);
// 下面这两行代码的区别
int[][] arr4 = {{1, 2, 3} , {2, 3, 4} , {100}};
// 在二维数组中,元素不能省略大括号,因为如果你没有写大括号,则会导致数据类型的改变
// 导致数据类型不匹配从而报错
// int[][] arr4 = {{1, 2, 3} , {2, 3, 4} , 100};
数组的几种写法
int[] a = new int[];
int a[] = new int[];
int[] a = {1, 2, 3};
int[] a = new int[]{1, 2, 3};
int[] a[] = new int[][];
int[][] a = new int[][];
int a[][] = new int[][];
int[][] a = {{1, 2}, {2, 3}, {3, 4}};
// int[][]中的中括号里面不能在输入值了,因为你已经在后面定义好了该二维数组的值了
int[][] a = new int[][]{{1, 2}, {2, 3}, {3, 4}};
推荐写法
int[] a = {1, 2, 3};
int[] a = new int[];
int[][] a = {{1, 2}, {2, 3}, {3, 4}};
int[][] a = new int[][];
可变参数
也就是说当你要计算多组数,第一组要计算两个数的和,第二组要计算三个数的和,第三组要计算四个数的和。。。
如果利用重载的方法来写那就太麻烦了,利用数组但又不知道要创建多少个数组
因为每一组都是计算多个数的总和,每一组都是一个方法的话那就要写多个方法,所以这里可以利用可变参数来实现上面的要求,也就是我传入多少个参数,那么就计算多少个参数的总和。
class VarParameters {
// int... 表示的是int类的可变参数,所以接收的数据类型是int类型,可变参数和一维数组差不多,唯一的区别就是可变参数不需要定义元素个数,可变参数是传入多少个元素,那么就有多少个元素值
// 调用方式和一维数组差不多
public int sum(int... num) {
int a = 0;
// 可变参数相当于是一个一维数组,所以可以使用 length 参数
for (int i = 0; i < num.length; i++) {
// 因为可变参数相当于是一个一维数组,所以这里 num[i] 的意思和一维数组中的是一个意思
// for 遍历各个数,i表示第几位数的意思,和一维数组是一个意思
a = a + num[i];
}
return a;
}
}
public class VariadicParameters {
public static void main(String[] args) {
VarParameters var = new VarParameters();
System.out.println(var.sum(1, 2)); // 输出 3
System.out.println(var.sum(4, 6, 9)); // 输出 19
}
}
可变参数注意事项
可变参数可以和普通类型的参数一起放在形参列表中,但必须保证可变参数放在最后
// 可变参数可以和普通类型的参数一起放在形参列表中,但必须保证可变参数放在最后 public void num(int a, int... b) { } /* 错误写法 public void num1(int... b, int a) { } */
一个形参列表中只有只能出现一个可变参数
// 一个形参列表中只有只能出现一个可变参数 public void num(int a, int... b) { } /* 错误写法 public void num1(int... a1, int... b) { } */
可变参数就相当于是一个一维数组
class Detail { public void num(int a, int... b) { } } public class VariadicParametersDetail { public static void main(String[] args) { int[] a = {1, 2, 3}; Detail var = new Detail(); // 因为可变参数就相当于是一个一维数组,所以可以直接把一维数组直接赋值给可变参数 var.num(2, a); } }