怀抱观古今,寝食展戏谑。这篇文章主要讲述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);
文章图片
(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
文章图片
(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]);
文章图片
(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的工具文档,我们查找到了相应的工具类.
文章图片
代码如下:
public static void main(String[] args)
int[] arr = 1,2,3,4,5;
System.out.println(Arrays.toString(arr));
文章图片
?二、数组作为参数的方法 1.理解引用类型 (1)参数传内置类型
文章图片
我们用 内置类型作为参数,进行交换变量,但是最后编译的结果 两个变量却并未发生交换.
这是为什么呢?
文章图片
(2)参数传数组类型
文章图片
结果:
文章图片
我们用
数组作为参数
,进行交换变量,编译运行后,发现成功交换
两个变量的值。此时数组名 arr 是一个 “引用”
. 当传参的时候, 是按照引用传参
.那么为什么传引用类型可以 形参可对实参进行操作呢?
这里我们就要先从内存说起
数组在内存中的储存:
文章图片
如下图:
文章图片
总结:
(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个部分
文章图片
文章图片
关于上面的划分方式, 后面慢慢理解. 此处我们重点理解
虚拟机 栈 和 堆
.(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]);
// 这个写法毫无疑问也是错的,没对象,你怎么访问对象里的东西?
文章图片
文章图片
???三、数组作为方法的返回值代码示例:
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;
文章图片
※思考题※
题目一:
输出是什么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;
文章图片
题目二:
输出是什么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;
文章图片
题解:
public class TheDefinitionAndUseOfArrays
public static void main(String[] args)
int[] array = 1,2,3,4,5;
int[] array2 = array;
这代表array2 这个引用 指向 引用array指向 的对象
array 和 array2 指向的是同一个对象
文章图片
?四、数组练习 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);
文章图片
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当中copyOf方法的具体实现
文章图片
首先 Arrays.copyOf() 的返回类型是 int [ ] ,第一个参数是 原数组(要拷贝的数组),第二个参数是新数组的长度(可以自己定),如果新的数组的长度比原数组长的话,大于原数组长度的元素都补为0 。 具体如下所示…
文章图片
(2)copyOfRange()
我们先通过JDK文档来查看这个工具类的功能
文章图片
功能:将指定数组的指定范围复制到新的数组中.
具体看一下Java当中copyof方法的具体实现
文章图片
?copyOfRange 方法的返回类型是 int [ ] ,第一个参数是 原数组 ,第二、三参数是要拷贝原数组数据的下标 ,一定要切记 是左闭右开的区间 , [ from , to ).
代码示例
文章图片
文章图片
我们打开 System.arraycopy 方法的具体实现,发现没有和上面几种拷贝方法的实现过程,System.arraycopy 有前面的 native 可知,这是一个本地方法。
本地方法
System.arraycopy 没有返回值,第一个参数原数组(要拷贝的数组),第二个参数是原始数组要拷贝的下标,第三个参数是目的地数组 ,第四个参数是 目的地数组的下标,第五个数组是要拷贝的长度.
代码示例:
文章图片
注意点:
??System.arraycopy 最后一个参数 ——要拷贝的数组长度,这个数据不能超过原数组的长度,否则编辑器会发生错误报告:数组越界。
clone可以理解为是一份资料的备份
代码示例:
文章图片
?五、理解深拷贝与浅拷贝
浅拷贝
:复制基本类型的属性;引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针,不复制堆内存中的对象。文章图片
深拷贝
:复制基本类型的属性;引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针和堆内存中的对象。文章图片
假设B复制了A,修改A的时候,看B是否发生变化:
如果B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值)
如果B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不同的值)
通俗来说就是:
文章图片
?六、二维数组 1.二维数组的创建
文章图片
跟一维数组几乎一样,只要初始化了数据,你的[][]里就不能有数字的存在
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();
// 换行
文章图片
如果计算的算,每个二维数组都自己去算它有几个元素吧。
怎么去获得 行 和 列?
这里就引用C语言的一个概念,
二维数组是一个特殊的一维数组
经过前面讲解,大家都知道数组是存储在堆上的,再加上面这句话的概念
文章图片
修改代码如下:
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();
//换行
文章图片
方法三:二维数组也有对应的 方法:
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));
文章图片
?七、不规则的二维数组 (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));
编译结果:
文章图片
首先我们规定了一个 有两行的二维数组
int [ ] [ ] arr = new int [2] [ ];
我们自己给每一行的数组规定有多少列。
arr [ 0 ] = new int [ ]1,2,3
arr [ 1 ] = new int [ ]4,5 ;
这就是不规则的二维数组的定义。
(2)内存中的不规则二维数组
文章图片
【JAVA SE—— 数组(详细!!!)】与规则的二维数组内存存储基本相同。
推荐阅读
- Shell脚本之免交互(EOFExpect)
- Java Record 的一些思考 - 序列化相关
- netty系列之:选byte还是选message?这是一个问题
- MySQL面试10道不得不会的MySQL基础面试题
- JavaScript数据结构之Object
- linux防火墙综合
- tcpdump 命令的常用选项(一)
- 关于V2代理和Burp的一些实验
- Go 通过 Map/Filter/ForEach 等流式 API 高效处理数据