JAVA SE—— 数组(详细!!!)

怀抱观古今,寝食展戏谑。这篇文章主要讲述JAVA SE—— 数组(详细!!!)相关的知识,希望能为你提供帮助。
@TOC
?一、 数组基本用法 1.数组的作用能让我们批量创建相同类型的变量
2.数组的创建下面这三种创建方式都是可以的

int[] arr1=new int[] 1,2,3,4; int[] arr2=1,2,3,4; int[] arr3=new int[4];

3. 数组的使用 (1)获取长度注意事项
代码示例:
public static void main(String[] args) int[] array = 1,2,3,4,5; System.out.println(array.length);

JAVA SE—— 数组(详细!!!)

文章图片

(2)访问数组中的元素注意事项:
代码示例:
public static void main(String[] args) int[] array = 1,2,3,4,5; //获取数组中的元素的个数 //System.out.println(array.length); //访问数组中的元素 System.out.println(array[1]); // 执行结果: 2 System.out.println(array[2]); // 执行结果: 3//修改数组中的元素 array[2] = 100; System.out.println(array[2]); // 执行结果: 100

JAVA SE—— 数组(详细!!!)

文章图片

(3)下标越界数组下标从0开始,范围是 [0,arr.length) ,左闭右开的区间,或者是[ 0,arr.length-1].
如果我们将下标的值超出数组的范围…
如下所示
public static void main(String[] args) int[] arr = 1,2,3,4,5,6; System.out.println(arr[100]);

JAVA SE—— 数组(详细!!!)

文章图片

(4)遍历数组(三种方法)1.遍历方式(一)----- for循环
public static void main(String[] args) int[] arr = 1, 2, 3; for (int i = 0; i < arr.length; i++) System.out.println(arr[i]);

2.遍历方式(二)----> for-each
public static void main(String[] args) int[] arr = 1,2,3,4,5; for (int x:arr) System.out.print(x+" ");

两种遍历的方式我们介绍完了,那么for循环和for-each有什么区别?
3.遍历方式(三)-----> 使用操作数组的工具类进行数组的打印(Arrays)
?Arrays 就是操作java数组的工具类,你要对数组做什么事情,就可以通过他来做,当然有些事情他是完成不了的.
?比如说:我们要打印数组,我们本来是用for循环 或者 for-each 来写的,但是我们也可以用Arrays的工具类打印.
?通过JDK的工具文档,我们查找到了相应的工具类.
JAVA SE—— 数组(详细!!!)

文章图片

代码如下:
public static void main(String[] args) int[] arr = 1,2,3,4,5; System.out.println(Arrays.toString(arr));

JAVA SE—— 数组(详细!!!)

文章图片

?二、数组作为参数的方法 1.理解引用类型 (1)参数传内置类型
JAVA SE—— 数组(详细!!!)

文章图片

我们用 内置类型作为参数,进行交换变量,但是最后编译的结果 两个变量却并未发生交换.
这是为什么呢?
JAVA SE—— 数组(详细!!!)

文章图片

(2)参数传数组类型
JAVA SE—— 数组(详细!!!)

文章图片

结果:
JAVA SE—— 数组(详细!!!)

文章图片

我们用数组作为参数,进行交换变量,编译运行后,发现成功交换两个变量的值。此时数组名 arr 是一个 “引用”. 当传参的时候, 是按照引用传参.
那么为什么传引用类型可以 形参可对实参进行操作呢?
这里我们就要先从内存说起
数组在内存中的储存:
JAVA SE—— 数组(详细!!!)

文章图片

如下图:
JAVA SE—— 数组(详细!!!)

文章图片

总结:
(3)JVM内存区域划分
public class TheDefinitionAndUseOfArrays public static void main(String[] args) int[] array =1,2,3,4,5; int a = 10;

array 和 a 都是局部变量,在栈上开辟空间
那么问题来了,a的空间里存的是 10,但是数组后面的数据,放在哪里?
和 10 一样放在栈上?
对象是存放在 堆上的
看一下JVM的5个部分
JAVA SE—— 数组(详细!!!)

文章图片

JAVA SE—— 数组(详细!!!)

文章图片

关于上面的划分方式, 后面慢慢理解. 此处我们重点理解 虚拟机 栈 和 堆.
(4)初始null指针有空指针,那引用有空引用(引用里面存的地址是空的)吗?
public class TheDefinitionAndUseOfArrays public static void main(String[] args) int[] array = 1,2,3,4,5; int[] array1 = null; //当一个引用被赋予null,就代表这该引用不指向任何对象 // 既然该引用不指向任何对象,那么我这样写代码会怎么样? System.out.println(array1.length); // 求一个空引用所指向的对象的长度,但是空引用不会指向任何一个对象的 // 何来的长度?那么代码运行的效果如何? 图14,由图可知该写法是错误的,另外引用被指为null,堆上是不会分配内存给它的 // 意思是你都不创建任何对象,你还想拿我空间,疯了?System.out.println(array1[0]); // 这个写法毫无疑问也是错的,没对象,你怎么访问对象里的东西?

JAVA SE—— 数组(详细!!!)

文章图片

JAVA SE—— 数组(详细!!!)

文章图片

???三、数组作为方法的返回值代码示例:
public static void main(String[] args) int[] arr = 1, 2, 3; transform(arr); printArray(arr); public static void printArray(int[] arr) for (int i = 0; i < arr.length; i++) System.out.println(arr[i]); public static void transform(int[] arr) for (int i = 0; i < arr.length; i++) arr[i] = arr[i] * 2;

这个代码固然可行, 但是破坏了原有数组. 有时候我们不希望破坏原数组, 就需要在方法内部创建一个新的数组, 并由方法返回出来。
修改后的代码:
public static void main(String[] args) int[] arr = 1, 2, 3; int[] output = transform(arr); printArray(output); public static void printArray(int[] arr) for (int i = 0; i < arr.length; i++) System.out.println(arr[i]); 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;

JAVA SE—— 数组(详细!!!)

文章图片

※思考题※题目一:输出是什么
import java.util.Arrays; public class TheDefinitionAndUseOfArrays public static void main(String[] args) int[] array = 1,2,3,4,5; func1(array); System.out.println(Arrays.toString(array)); // 图 18public static void func1(int[] array) array = new int[]11,2,13,4,51;

JAVA SE—— 数组(详细!!!)

文章图片

题目二:输出是什么
import java.util.Arrays; public class TheDefinitionAndUseOfArrays public static void main(String[] args) int[] array = 1,2,3,4,5; func2(array); System.out.println(Arrays.toString(array)); public static void func2(int[] array) array[0] = 99;

JAVA SE—— 数组(详细!!!)

文章图片

题解:
public class TheDefinitionAndUseOfArrays public static void main(String[] args) int[] array = 1,2,3,4,5; int[] array2 = array; 这代表array2 这个引用 指向 引用array指向 的对象 array 和 array2 指向的是同一个对象

JAVA SE—— 数组(详细!!!)

文章图片

?四、数组练习 1.模拟实现toString题目要求:
public static String my_toString(int[] arr) String s="["; for(int i=0; i< arr.length; i++)s=s+arr[i]; if(i< arr.length-1) s+=","; s+="]"; return s; public static void main(String[] args) int[] arr = 1, 2, 3, 4, 5, 6; String ss=my_toString(arr); System.out.println(ss);

JAVA SE—— 数组(详细!!!)

文章图片

2.数组拷贝数组的拷贝方式
//数组拷贝 public static void main(String[] args) int[] arr = 1,2,3,4,5; int[] copy = new int[arr.length]; for (int i = 0; i < arr.length ; i++) copy[i] = arr[i]; System.out.println(Arrays.toString(copy));

在这种拷贝方式中,我们首先通过 new 一个新的和 arr 一样长度数组 copy,再通过 for 循环将 arr 数组中的内容 一 一赋给copy数组,达到 最终的数组拷贝的效果.
(1)copyOf()
我们先通过JKD的工具文档,来看一下拷贝工具的用法
JAVA SE—— 数组(详细!!!)

文章图片

功能:复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度.
具体看一下Java当中copyOf方法的具体实现
JAVA SE—— 数组(详细!!!)

文章图片

首先 Arrays.copyOf() 的返回类型是 int [ ] ,第一个参数是 原数组(要拷贝的数组),第二个参数是新数组的长度(可以自己定),如果新的数组的长度比原数组长的话,大于原数组长度的元素都补为0 。 具体如下所示…
JAVA SE—— 数组(详细!!!)

文章图片

(2)copyOfRange()
我们先通过JDK文档来查看这个工具类的功能
JAVA SE—— 数组(详细!!!)

文章图片

功能:将指定数组的指定范围复制到新的数组中.
具体看一下Java当中copyof方法的具体实现
JAVA SE—— 数组(详细!!!)

文章图片

?copyOfRange 方法的返回类型是 int [ ] ,第一个参数是 原数组 ,第二、三参数是要拷贝原数组数据的下标 ,一定要切记 是左闭右开的区间 , [ from , to ).
代码示例
JAVA SE—— 数组(详细!!!)

文章图片

JAVA SE—— 数组(详细!!!)

文章图片

我们打开 System.arraycopy 方法的具体实现,发现没有和上面几种拷贝方法的实现过程,System.arraycopy 有前面的 native 可知,这是一个本地方法。
本地方法
System.arraycopy 没有返回值,第一个参数原数组(要拷贝的数组),第二个参数是原始数组要拷贝的下标,第三个参数是目的地数组 ,第四个参数是 目的地数组的下标,第五个数组是要拷贝的长度.
代码示例:
JAVA SE—— 数组(详细!!!)

文章图片

注意点:
??System.arraycopy 最后一个参数 ——要拷贝的数组长度,这个数据不能超过原数组的长度,否则编辑器会发生错误报告:数组越界。
clone可以理解为是一份资料的备份
代码示例:
JAVA SE—— 数组(详细!!!)

文章图片

?五、理解深拷贝与浅拷贝浅拷贝:复制基本类型的属性;引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针,不复制堆内存中的对象。
JAVA SE—— 数组(详细!!!)

文章图片

深拷贝:复制基本类型的属性;引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针和堆内存中的对象。
JAVA SE—— 数组(详细!!!)

文章图片

假设B复制了A,修改A的时候,看B是否发生变化:
如果B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值)
如果B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不同的值)
通俗来说就是:
JAVA SE—— 数组(详细!!!)

文章图片

?六、二维数组 1.二维数组的创建
JAVA SE—— 数组(详细!!!)

文章图片

跟一维数组几乎一样,只要初始化了数据,你的[][]里就不能有数字的存在
public class TheDefinitionAndUseOfArrays public static void main(String[] args) // 创建一个 2行3列的二维数组 int[][] array = 1,2,3,4,5,6; int[][] array2 = new int[][]1,2,3,4,5,6; int[][] array3 = new int[2][3];

2.二维数组的打印方法一:
public class TheDefinitionAndUseOfArrays public static void main(String[] args) // 创建一个 2行3列的二维数组 int[][] array = 1,2,3,4,5,6; int[][] array2 = new int[][]1,2,3,4,5,6; int[][] array3 = new int[2][3]; print(array); public static void print(int[][] array) // 按照我们以前对C的理解,二维数组的存储模式应该为 图60 for (int i = 0; i < 2; i++) for (int j = 0; j < 3; j++) //打印一行数据 System.out.print(array[i][j] + " "); System.out.println(); // 换行

JAVA SE—— 数组(详细!!!)

文章图片

如果计算的算,每个二维数组都自己去算它有几个元素吧。
怎么去获得 行 和 列?
这里就引用C语言的一个概念,二维数组是一个特殊的一维数组
经过前面讲解,大家都知道数组是存储在堆上的,再加上面这句话的概念
JAVA SE—— 数组(详细!!!)

文章图片

修改代码如下:
public class TheDefinitionAndUseOfArrays public static void main(String[] args) // 创建一个 2行3列的二维数组 int[][] array = 1,2,3,4,5,6; int[][] array2 = new int[][]1,2,3,4,5,6; int[][] array3 = new int[2][3]; print(array); // 这里我们在用实例证明一下 // array.length 是否能的得到 行数 2 System.out.println(array.length); // array[下标].length 是否能得到 列数3 System.out.println(array[0].length); System.out.println(array[1].length); public static void print(int[][] array) // 按照我们以前对C的理解,二维数组的存储模式应该为图60 for (int i = 0; i < array.length; i++) for (int j = 0; j < array[i].length; j++) //打印一行数据 System.out.print(array[i][j] + " "); System.out.println(); // 换行

方法二:
public class TheDefinitionAndUseOfArrays public static void main(String[] args) int[][] array = 1,2,3,4,5,6; print(array); public static void print(int[][] array) for (int[] ret:array) // array元素的数据类型是一个一维数组,我就需要一个相同的类型的变量来接收 for (int x:ret) // ret是一个一维数组的数组名,接下来就跟前面使用foreach是一样,将 引用ret 所指向的对象(数组)的元素, // 读取并赋值给 与其元素类型相同的变量, 我们再将其输出。就可以了 System.out.print(x + " " ); System.out.println(); //换行

JAVA SE—— 数组(详细!!!)

文章图片

方法三:二维数组也有对应的 方法:Arrays.deepToString( 数组名 )
import java.util.Arrays; public class TheDefinitionAndUseOfArrays public static void main(String[] args) int[][] array = 1,2,3,4,5,6; System.out.println(Arrays.deepToString(array));

JAVA SE—— 数组(详细!!!)

文章图片

?七、不规则的二维数组 (1)不规则二维数组定义 Java中不规则二维数组的定义C语言中数组的定义
int[][2] = 1,2,3,4,5,6,7;

而在Java中我们只能 定义行,列不用规定值
int[][] arr = new int[2][];

代码如下:
public static void main(String[] args) int[][] arr = new int[2][]; arr[0] = new int[]1,2,3; arr[1] = new int[]4,5; System.out.println(Arrays.deepToString(arr));

编译结果:
JAVA SE—— 数组(详细!!!)

文章图片

首先我们规定了一个 有两行的二维数组
int [ ] [ ] arr = new int [2] [ ];

我们自己给每一行的数组规定有多少列。
arr [ 0 ] = new int [ ]1,2,3 arr [ 1 ] = new int [ ]4,5 ;

这就是不规则的二维数组的定义。
(2)内存中的不规则二维数组
JAVA SE—— 数组(详细!!!)

文章图片

【JAVA SE—— 数组(详细!!!)】与规则的二维数组内存存储基本相同。

    推荐阅读