欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

JavaSE之数组总结

时间:2023-08-01

目录

一、数组基本用法

1.什么是数组

2.数组的创建

3.数组的使用

二、数组作为方法的参数

1.初识 JVM 内存区域划分

2.一道题:

 3.null

 4.数组作为方法的返回值

三、数组的一些练习

1.数组转字符串

2.数组的拷贝

3.为整型数组分配元素

4.查找整型数组中指定元素(二分查找)

 四、二维数组


一、数组基本用法

1.什么是数组

数组本质上就是让我们能 "批量" 创建相同类型的变量,在 Java 中, 数组中包含的变量必须是相同类型

2.数组的创建 (1)动态初始化:数据类型[] 数组名称 = new 数据类型 []{ 初始化数据 };  new:一个关键字,实例化一个对象,这说明数组是一个对象 如:int[] arr = new int[3];//创建了一个长度为3的数组        int[] arr = new int[]{1,2,3};//创建了一个长度为3的数组并且初始化为1,2,3 (2)静态初始化:数据类型[] 数组名称 = { 初始化数据 };如:int[] array = {1, 2, 3}; 其实数组也可以写成int arr[] = {1, 2, 3}; 这样就和 C 语言更相似了、但是我们还是更推荐写成 int[] arr 的形式、int和 [] 是一个整体.

3.数组的使用

(1)使用 arr.length 能够获取到数组的长度。“.”这个操作是成员访问操作符

(2)使用 [ ] 按下标取数组元素、需要注意, 下标从 0 开始计数

(3)使用 [ ] 操作既能读取数据, 也能修改数据

(4)下标访问操作不能超出有效范围 [0, length - 1] , 如果超出有效范围, 会出现下标越界异常java.lang.ArrayIndexOutOfBoundsException(IIEA中的描述)

(5)遍历数组:

import java.util.Arrays;//法三public class Array{ public static void main(String[] args){ int[] arr = {1, 2, 3}; //法一:for循环 for(int i = 0; i < arr.length; i++){ System.out.print(arr[i]+" "); } //法二:for-each循环(增强for循环)for-each循环拿不到下标,for循环可以拿到下标 for-each循环更多的用于集合中 for(int i : arr){ System.out.print(arr[i]+" "); } //法三:借助Java的操作数组的工具类Arrays System.out.println(Arrays.toString(arr));//toString:将参数的数组以字符串的形式输出}

二、数组作为方法的参数

1.初识 JVM 内存区域划分

(1)程序计数器 (PC Register): 只是一个很小的空间 , 保存下一条执行的指令的地址 、 (2)虚拟机栈 (JVM Stack): 重点是存储 局部变量表 ( 当然也有其他信息 )、 我们刚才创建的 int[] arr 这样的存储地址的引用就是在这里保存、 (3)本地方法栈 (Native Method Stack): 本地方法栈与虚拟机栈的作用类似 、 只不过保存的内容是 Native方法( 指这些 C++ 实现的, 再由 Java 来调用的函数 )的局部变量、在有些版本的 JVM 实现中 ( 例如 HotSpot), 本地方法栈和虚拟机栈是一起的 、 JVM 是一个基于 C++ 实现的程序、在 Java 程序执行过程中, 本质上也需要调用 C++ 提供的一些函数进行和操作系统底层进行一些交互、因此在 Java 开发中也会调用到一些 C++ 实现的函数 (4)堆 (Heap): JVM 所管理的最大内存区域 、 使用 new 创建的对象都是在堆上保存 ( 例如前面的 new int[]{1, 2, 3} )  (5)方法区 (Method Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据、 方法编译出的字节码就是保存在这个区域 、 (6)运行时常量池 (Runtime Constant Pool): 是方法区的一部分 , 存放字面量 ( 字符串常量 ) 与符号引用 、( 注意 从 JDK 1.7 开始 , 运行时常量池在堆上 )

2.一道题:

在这之前,我们先来看看什么是引用?

引用相当于一个 "别名", 也可以理解成一个指针、创建一个引用只是相当于创建了一个很小的变量, 这个变量保存了一个整数, 这个整数表示内存中的一个地址。我们来看看 int[] arr = new int[]{1, 2, 3} 这样的代码的 内存布局。

 现在我们来看这条题,运行下面的代码,它输出的是什么?

public class Test{ public static void func1(int[] array){ array = new int[]{11, 2, 13, 4, 51, 61}; } public static void func2(int[] array){ array[0] = 899; } public static void main2(String[] args) { int[] array = {1, 2, 3, 4, 5, 6}; System.out.print(Arrays.toString(array)); System.out.println(); func1(array); System.out.print(Arrays.toString(array)); System.out.println(); func2(array); System.out.print(Arrays.toString(array)); }}

Tips:

(1)func1(array);此时数组名 array 是一个 "引用" 、当传参的时候, 是按照引用传参,也叫按值传递,只不过这个值是地址而已

(2)所谓的 "引用" 本质上只是存了一个地址、Java 将数组设定成引用类型, 这样的话后续进行数组参数传参, 其实 只是将数组的地址传入到函数形参中、这样可以避免对整个数组的拷贝(数组可能比较长, 那么拷贝开销就会很大)

编译运行该代码,输出如下:

1 2 3 4 5 6

1 2 3 4 5 6

899 2 3 4 5 6 

分析如下图:

 3.null null 在 Java 中表示 " 空引用" , 也就是一个无效的引用, 不能对这个内存进行任何读写操 作 Java 中并没有约定 null 和 0 号地址的内存有任何关联。 如:int[] arr = null;//这表示arr不指向任何对象,如果此时我们System.out.println(arr[0]);编译器会报一个 NullPointerException(空指针)的错 注意:C语言的空指针NULL是大写,而java是小写

 4.数组作为方法的返回值

比如:我们要写一个方法, 将数组中的每个元素都 * 2(2种方式实现代码)

法一:

public class Test { public static void main(String[] args) { int[] arr = {1, 2, 3}; transform(arr); for(int i : arr){ System.out.print(i + " "); } } public static void transform(int[] arr) { for (int i = 0; i < arr.length; i++) { arr[i] = arr[i] * 2; } } }

这个实现方式也不是不行,只不过破坏了原数组,要不想破坏原数组,就需要在方法内部创建一个新的数组, 并由方法返回出来

法二:

public class Test { public static void main(String[] args) { int[] arr = {1, 2, 3}; transform(arr); for(int i : ret){ System.out.print(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; } }

这样的话就不会破坏原有数组了 、另外由于数组是引用类型, 返回的时候只是将这个数组的首地址返回给函数调用者 , 没有拷贝数组内容 , 从而比较高效

三、数组的一些练习

1.数组转字符串

(1)首先,我们先认识一下“包”:

程序开发也不是从零开始, 而是要站在巨人的肩膀上、像我们很多程序写的过程中不必把所有的细节都自己实现, 已经有大量的标准库(JDK提供好的代码)和海量的第三方库(其他机构组织提供的代码)供我们直接使用、这些代码就放在一个一个的 "包" 之中,我们可以使用的 "包" , 有成千上万 (2) Java 中提供了 java.util.Arrays 包 , 其中包含了一些操作数组的常用方法 toString(int[] a):将参数的整型数组以字符串的形式输出,返回值为static String toString(float[] a):将参数的浮点型数组以字符串的形式输出,返回值为static String ......其他数据类型的数组以此类推

import java.util.Arrayspublic class Test { public static void main(String[] args) { int[] arr = {1,2,3,4,5,6}; String newArr = Arrays.toString(arr); System.out.println(newArr); }}

编译并运行该代码,输出如下:

[1,2,3,4,5,6]

其实,我们也可以模拟实现toString(int[] a):

public class Test{ public static String myToString(int[] array){ if(array == null){ return null; }//注意考虑如果传过来是空指针 String str = "["; for(int i = 0; i < array.length; i++){ str = str + array[i]; if(i != array.length - 1){ str = str +",";// 除了最后一个元素之外, 其他元素后面都要加上"," } } str = str + "]"; return str; } public static void main6(String[] args) { int[] array = {1, 2, 3, 4, 5, 6}; String ret = myToString(array); System.out.println(ret); }}

2.数组的拷贝

(1)法一:

Arrays类中的方法copy.Of(int[] original,int newlength),返回值为static int[],该方法针对整型数组,可以实现数组的拷贝:

(其他数据类型的数组可以在上面的基础上改一改,如:浮点型数组copy.Of(float[] original,int newlength),返回值为static float[]......)

import java.util.Arrayspublic class Test{ public static void main(String[] args){ int[] array = {1, 2, 3, 4, 5, 6}; int[] ret = Arrays.copyOf(array,array.length*2); System.out.println(Arrays,toString(ret)); }}

编译运行该程序,输出如下:

[1,2,3,4,5,6,0,0,0,0,0,0] 

其实还可以限制范围的拷贝,这个需要用到方法copyOfRange(int[] original,int from,int to)

① original:源数组

②from:开始拷贝的位置

③to:结束拷贝的位置     

注意范围为[from,to),左闭右开

import java.util.Arrayspublic class Test{ public static void main(String[] args){ int[] array = {1, 2, 3, 4, 5, 6}; int[] ret = Arrays.copyOfRange(array,1,3); System.out.println(Arrays,toString(ret)); }}

编译并运行该代码,输出如下:

[2,3] 

(2)法二:

利用for循环将数组中的元素一个一个的拷贝

import java.util.Arrays;public class Test{ public static int[] myCopy(int[] array,int newlength){ int[] copy = new int[newlength]; for(int i = 0; i < newlength; i++){ copy[i] = array[i]; } return copy; } public static void main(String[] args){ int[] array = {1, 2, 3, 4, 5}; int newlength = 3; int[] ret = myCopy(array,newlength); System.out.println(Arrays.toString(ret)); }}

(3)法三:

System类里面的方法arraycopy(Object src,int srcPos,Object dest,int destPos,int length);返回值为static void

①src:源数组

②srcPos:从源数组这个位置开始拷贝(下标)

③dest:目标数组

④destPos:拷贝到目标数组的这个位置(下标)

⑤length:拷贝长度

import java.util.Arrayspublic class Test{ public static void main(String[] args){ int[] array = {1, 2, 3, 4, 5, 6}; int[] copy = System.arraycopy(array,0,copy,0,array.length); System.out.println(Arrays,toString(copy)); }}

(4)法四:

利用方法clone():

public class Test{ public static void main(String[] args){ int[] array = {1, 2, 3, 4, 5, 6}; int[] copy = array.clone();//产生一个副本 System.out.println(Arrays,toString(copy)); }}

这4种方法都是浅拷贝。

 浅拷贝:浅拷贝只复制某个对象的引用,而不复制对象本身,新旧对象还是共享同一块内存

深拷贝:深拷贝会创造一个一摸一样的对象,新对象和原对象不共享内存,修改新对象不会改变原对对象。

3.为整型数组分配元素

我们需要用到Arrays类中的方法fill(int[] a,int val),返回值为static void

                                                  fill(int[] a,int fromIndex,int toIndex,int val),返回值为static void

①a:要分配元素的数组

②fromIndex:开始分配的位置(下标)

③toIndex:结束分配的位置(下标)

④val:要分配的值

注意范围:[fromIndex,toIndex)

public class Test{ public static void main10(String[] args){ int[] array = new int[10]; Arrays.fill(array,2,6,66);//从[2,6)下标填充66 System.out.println(Arrays.toString(array)); }}

4.查找整型数组中指定元素(二分查找)

不同与C语言,java实现二分查找很简单,只需要用到Arrays类中的方法binarySearch(int[] a,int key),返回值为static int

public class Test{public static void main(String[] args) { int[] array = {1, 2, 3, 4, 5, 6}; System.out.println(Arrays.binarySearch(array,9)); }}

编译并运行该代码,输出如下:

-7

为什么是-7呢?这时候我们就要看实现它的源码了

 四、二维数组

1.基本语法

数据类型 [][] 数组名称 = new 数据类型 [ 行数 ][ 列数 ] { 初始化数据 }; 2.二维数组的遍历。(二维数组本质上是一维数组)

public class Test{ public static void main(String[] args) { int[][] array = {{1, 2, 3},{4, 5, 6}}; //法一: 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(); } //法二: for(int[] ret : array){ for(int i:ret){ System.out.print(i+" "); } System.out.println(); } //法三: System.out.println(Arrays.deepToString(array));//[[1, 2, 3], [4, 5, 6]] }}

3.java中的二维数组不能省略行;如果省略列,会报一个空指针异常的错,但是也有解决办法

public class Test{ public static void main(String[] args){ int[][] array = new int[2][];//java中不能省略行;不能省略列(否则会报空指针异常)的错,但是可以解决这个报错 array[0] = new int[3]; array[1] = new int[2];//不规则的二维数组 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(); }}

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。