目录
一、数组基本用法
1.什么是数组
2.数组的创建
3.数组的使用
二、数组作为方法的参数
1.初识 JVM 内存区域划分
2.一道题:
3.null
4.数组作为方法的返回值
三、数组的一些练习
1.数组转字符串
2.数组的拷贝
3.为整型数组分配元素
4.查找整型数组中指定元素(二分查找)
四、二维数组
数组本质上就是让我们能 "批量" 创建相同类型的变量,在 Java 中, 数组中包含的变量必须是相同类型
(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:将参数的数组以字符串的形式输出 }
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
分析如下图:
比如:我们要写一个方法, 将数组中的每个元素都 * 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)首先,我们先认识一下“包”:
程序开发也不是从零开始, 而是要站在巨人的肩膀上. 像我们很多程序写的过程中不必把所有的细节都自己实现, 已经有大量的标准库(JDK提供好的代码)和海量的第三方库(其他机构组织提供的代码)供我们直接使用. 这些代码就放在一个一个的 "包" 之中,我们可以使用的 "包" , 有成千上万 (2) Java 中提供了 java.util.Arrays 包 , 其中包含了一些操作数组的常用方法 toString(int[] a):将参数的整型数组以字符串的形式输出,返回值为static String toString(float[] a):将参数的浮点型数组以字符串的形式输出,返回值为static String ......其他数据类型的数组以此类推import java.util.Arrays public 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); } }
(1)法一:
Arrays类中的方法copy.Of(int[] original,int newlength),返回值为static int[],该方法针对整型数组,可以实现数组的拷贝:
(其他数据类型的数组可以在上面的基础上改一改,如:浮点型数组copy.Of(float[] original,int newlength),返回值为static float[]......)
import java.util.Arrays public 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.Arrays public 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.Arrays public 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种方法都是浅拷贝。
浅拷贝:浅拷贝只复制某个对象的引用,而不复制对象本身,新旧对象还是共享同一块内存
深拷贝:深拷贝会创造一个一摸一样的对象,新对象和原对象不共享内存,修改新对象不会改变原对对象。
我们需要用到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)); } }
不同与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(); } }