Java数组
2021/4/5 周一
复习内容: 数组的存储方式、Arrays.toString()、Arrays.sort()、Arrays.copyOf()、System.arraycopy()、数组排序、数组复制、数组扩容、数组作为方法参数等
如有错误,欢迎在评论区指出,非常感谢!
一、数组的存储方式
当我直接输出一个数组时,会发现结果是一串不认识的东西:
int [] arr = new int[]{12,34,56}};
System.out.println(arr);
-----------------控制台输出--------------------
[I@15db9742
这个 [I@15db9742 表示的是arr数组对象在内存中的地址信息,由此可引出 变量在Java中的存储方式:
- 基本数据类型的变量,是直接存储值;
- 引用数据类型的变量,存储的是对象的地址信息;
而Java的基本数据类型的变量只有8种,显然数组是引用数据类型
因此,数组是以地址信息的形式存储的,直接输出就是一串地址信息。
二、数组的方法
1.Arrays.toString(数组名)
如果想输出数组的具体内容,就可要用这个方法,它把数组中的元素用逗号隔开组装成一个字符串
int[] arr = new int[] {12,34,56};
System.out.println(Arrays.toString(arr));
----------------控制台输出-------------------
[12, 34, 56]
2.Arrays.sort(数组名)
这是JDK中直接提供的数组排序方法,通常是用于一维数值型的数组排序:
int[] arr = new int[] {6,23,45,12,-83,94,41};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
----------------控制台输出-------------------
[-83, 6, 12, 23, 41, 45, 94]
偶尔也会涉及一维String数组排序:
String[] arr = new String[] {"Harry","赫敏","罗恩","always","AAA","zzz"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
----------------控制台输出-------------------
[AAA, Harry, always, zzz, 罗恩, 赫敏]
大概可知排序规则是英文大写、英文小写、汉字
这里的汉字看起来好像没按顺序排,是因为它并不是根据拼音排的,而是Unicode码,罗恩的编码为 \u7 f57 \u6069,赫敏为 \u8 d6b \u654f,所以罗恩排在前面。
3.Arrays.copyOf(original, newLength)
数组复制的方法,有2个参数,表示从数组original拷贝newLength个元素到另外一个新数组中,并且返回该新数组。
其中拷贝有两种情况
(1)拷贝元素的个数小于或等于原数组长度
即newLength <= original.length,此时只会拷贝前newLength个元素:
int[] original = new int[] {12,34,56}; // 原数组长度为3
int[] newarr = Arrays.copyOf(original,2); // 只拷贝了前2个元素
System.out.println(Arrays.toString(newarr));
----------------控制台输出-------------------
[12, 34]
(2)拷贝元素的个数大于原数组长度
即newLength > original.length,这种情况下除了拷贝original中所有的元素以外,剩下的位置用默认值填充至newLength长度
int [] arr = new int[] {12,34,56};
System.out.println(Arrays.toString(Arrays.copyOf(arr,4))); // 省去了再声明一个新数组
----------------控制台输出-------------------
[12, 34, 56, 0] // 类型为int时默认值是0,所以新数组最后一个元素为0
此方法也经常用于数组扩容。
int []arr = new int[5]; // arr的初始长度为5
arr = Arrays.copyOf(arr,arr.length+5); // 长度加5
System.out.println(arr.length); // 结果为10
4.System.arraycopy(src, srcPos, dest, destPos, length)
该方法也是数组复制方法,它有5个参数:
src:源数组
srcPos:源数组中复制起始位置
dest:目标数组
destPos:目标数据中的保存起始位置
length: 要复制的数组元素的数量
表示从源src数组的srcPos下标位置,拷贝length个元素到目标dest数组中,并且从destPos下标开始存放:
int []src = new int[] {12,34,56};
int []dest = new int[5];
System.arraycopy(src, 0, dest, 1, src.length);
System.out.println(Arrays.toString(dest));
----------------控制台输出-------------------
[0, 12, 34, 56, 0]
System.arraycopy是没有返回值的。
与Arrays.copyOf相比,System.arraycopy可以不默认从第1个元素开始复制,操作更灵活,但更容易出错:
比如从源数组的srcPos位置开始,不够length个元素
System.arraycopy(src, 1, dest, 1, src.length);
// 从src的第2位开始,就没有3个元素了
或者 从目标数组dest的destPos下标位置开始,不足以存放length个元素
System.arraycopy(src, 0, dest, 4, src.length);
// 从dest的第5位开始往后,已经就没有3个位置了
都将产生 java.lang.ArrayIndexOutOfBoundsException数组下标越界异常
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at review.ErrorTest.main(ErrorTest.java:23)
三、数组作为方法的参数
基本数据类型作为方法参数,在方法中修改该参数的值,不会影响实参。
但当数组作为方法参数时,如果在方法中修改该数组里的元素,将会影响到实参数组里的元素。
除非在方法中让数组变量指向(引用)其它的数组,这种影响才不会存在。
用一个对比的例子来解释:
import java.util.Arrays;
public class ErrorTest {
public static void main(String[] args) {
int[] arr = new int[] {1,2,3};
int[] brr = new int[] {1,2,3};
change(arr,brr);
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(brr));
}
public static void change(int[] arr, int[] brr) {
arr[0] = 10; // 修改了arr数组中的元素
brr = new int[] {10,2,3}; // 该方法里的brr指向了一个新数组,原brr数组不受影响
}
}
-----------------控制台输出--------------------
[10, 2, 3]
[1, 2, 3]