数组入门
一、 Java数组的定义方式
程序清单1:
public class Test1 {
public static void main(String[] args) {
int[] array1 = {1, 2, 3};
int[] array2 = new int[]{1, 2, 3};
int[] array3 = new int[3];
}
}
二、 打印数组的每个元素
程序清单2:
public class Test2 {
public static void main(String[] args) {
int[] array = {1,2,3,4,5};
//1. for循环遍历数组
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
//2. 增强for循环打印数字元素
for (int x: array) {
System.out.print(x + " ");
}
System.out.println();
//3. 借助Java操作数组的工具类 Arrays.toString
//将参数的数组以字符串的形式输出
String ret = Arrays.toString(array);
System.out.println(ret);
}
}
程序清单3:
//模拟 System.out.println(Arrays.toString(array));
public class Test3 {
public static void main(String[] args) {
int[] array = {1,2,3,4,5};
System.out.println( myToString(array) );
}
public static String myToString(int[] array) {
if (array == null){
return "null";
}
String ret = "[";
for (int i = 0; i < array.length; i++) {
ret = ret + array[i];
if( i != array.length-1 ){
ret = ret + "," + " ";
}
}
ret = ret + "]";
return ret;
}
}
三、 数组、方法、引用
数组传参的时候,数组名表示一个引用,引用相当于指针
情况一:
程序清单4:
public class Test4 {
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7};
System.out.println(Arrays.toString(array));
fuc2(array);
System.out.println(Arrays.toString(array));
}
public static void fuc2(int[] array){
array[0] = 100;
}
}
分析:
形参拿到了数组的起始内存地址,并对数组第一个元素进行修改
情况二:
程序清单5:
public class Test5 {
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7};
System.out.println( Arrays.toString(array));
fuc1(array);
System.out.println( Arrays.toString(array));
}
public static void fuc1(int[] array){
array = new int[] {4,5,6,7,8,9,10};
}
}
输出结果:
分析:形参拿到了不同的地址,并不影响原来的数组
程序清单6:
public class Test6 {
public static void main(String[] args) {
//一个引用不能同时指向多个对象
int[] array1 = {1, 2, 3};
int[] array2 = new int[]{1, 2, 3};
int[] array3 = new int[3];
int[] array4 = {1,2,3,4,5};
int[] array5 = array4;
//这里表示array5这个引用指向了array4这个引用所指向的对象
//注意:引用只能指向对象
int[] array6 = null;
//这个引用不指向任何对象
//引用一定在栈上吗?不一定
//如果你定义了一个局部变量,那么一定在栈上
//如果你定义了实例成员变量,那就不一定在栈上了
}
}
四、 数组作为返回值
程序清单7:
//数组作为返回值
//破坏了原数组
public class Test7 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
transform(arr);
System.out.println(Arrays.toString(arr));
}
public static void transform(int[] arr) {
for (int i = 0; i < arr.length; i++) {
arr[i] = arr[i] * 2;
}
}
}
程序清单8:
//数组作为返回值
// 返回一个新的数组
public class Test8 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
int[] ret = transform(arr);
System.out.println( Arrays.toString(ret) );
}
public static int[] transform(int[] arr) {
int[] ret = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
ret[i] = arr[i] * 2;
}
return ret;
}
}
五、数组拷贝
1. Arrays.copyOf( ) 方法
Java 中 Arrays.copyOf( ) 方法的源代码,我们可以看到返回的是一个新的数组。
总结 Arrays.copyOf( ) 方法的格式:
其中 original 代表需要拷贝的数组,newLength 代表新数组的长度
Arrays.copyOf(original, newLength);
程序清单9:
public class Test9 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7};
int[] copy = Arrays.copyOf(arr, 5);
System.out.println(Arrays.toString(copy));
int[] copy2 = Arrays.copyOf(arr,10);
System.out.println(Arrays.toString(copy2));
}
}
输出结果:
当然,Arrays.copyOf( ) 方法也可以返回给自己原先的数组,但是底层依旧是 new 了一个新的数组。这个操作可以用于顺序表的扩容问题,请看下面代码:
import java.util.Arrays;
public class Test1 {
public static void main(String[] args) {
int[] arr = {1,3,5,7,9};
arr = Arrays.copyOf(arr, arr.length*2);
System.out.println(Arrays.toString(arr));
}
}
输出结果:
2. Arrays.copyOfRange( ) 方法
Java 中 Arrays.copyOf( ) 方法的源代码,我们可以看到返回的是一个新的数组。
其中 original 代表需要拷贝的数组,from 代表 original 需要拷贝的起始下标,to 代表 original 需要拷贝的终止下标。此外,from 和 to 遵循左闭右开。
Arrays.copyOf(original, from, to);
程序清单10:
public class Test10 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7};
int[] copy = Arrays.copyOfRange(arr, 1,3);
System.out.println(Arrays.toString(copy));
int[] copy2 = Arrays.copyOfRange(arr,1,10);
System.out.println(Arrays.toString(copy2));
}
}
输出结果:
在上面程序中,我们可以看到此方法有自动扩容现象。
3. arraycopy( ) 方法
在刚刚上面的 Arrays.copyOf( ) 方法 和 Arrays.copyOfRange( ) 方法中,我们看到它们的底层调用的都是 arraycopy( ) 方法,下面我们来看一下arraycopy( ) 方法。
这是 Java 中 arraycopy( ) 方法的源代码,我们只能看到传参的是些什么数据,因为它其实是 C / C++ 代码实现的。
arraycopy(src, pos, dest, destpos, length);
- src 代表需要拷贝的源头数组
- pos 代表 src 数组需要拷贝的起始下标
- dest 代表需要拷贝至的目的数组
- destpos 代表被拷贝的 dest 数组的起始下标
- length 代表需要拷贝的长度
我们可以把 arraycopy( ) 方法想象成一个模板,它既可以拷贝 String 类型的数据,又可以拷贝 int 类型的数据等等,等小伙伴理解到泛型的知识就明白了,现在先理解其可以是一个模板。
程序清单11:
public class Test11 {
public static void main(String[] args) {
int [] arr = {1,2,3,4,5};
int [] copy = new int[5];
System.arraycopy(arr,0,copy,1,4);
System.out.println(Arrays.toString(copy));
System.out.println("--------------------------");
System.out.println(Arrays.toString(arr));
System.arraycopy(arr,0,arr,1,4);
System.out.println(Arrays.toString(arr));
arr[0] = 100;
System.out.println(Arrays.toString(arr));
}
}
输出结果:
在程序清单11中,我们可以看到,当我们使用 arraycopy( ) 方法的时候,我们不但可以将原先的数组拷贝到一个新数组中去,也可以将原先的数组拷贝到原先的数组中。上述这个思想可以应用到数据结构的顺序表中的中间插入操作。
Over. 谢谢观看哟~