数组
Java中的数组
2021-05-27 356 3
简介 一维数组、二维数组的使用,初始化值、内存解析、Arrays工具类的使用
1. 一维数组
* 一、数组的概述
* 1.数组的理解:数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,
* 并通过编号的方式对这些数据进行统一管理。
*
* 2.数组相关的概念:
* >数组名
* >元素
* >角标、下标、索引
* >数组的长度:元素的个数
*
* 3.数组的特点:
* 1)数组是按顺序存储的
* 2)数组属于引用数据类型的变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型
* 3)创建数组对象会在内存中开辟一整块连续的空间
* 4)数组的长度一旦确定,就不能修改。
*
* 4. 数组的分类:
* ① 按照维数:一维数组、二维数组
* ② 按照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组
2. 一维数组的使用
* ① 一维数组的声明和初始化
* ② 如何调用数组的指定位置的元素
* ③ 如何获取数组的长度
* ④ 如何遍历数组
* ⑤ 数组元素的默认初始化值
* ⑥ 数组的内存解析
2.1 静态初始化 和 动态初始化
// ArrayInit.java package com.ylaihui.array; public class ArrayInit { public static void main(String[] args) { // 静态初始化 int[] array; array = new int[]{1,2,3,4,5}; // 动态初始化 int[] array2 = new int[5]; array2[0] = 1; array2[1] = 2; array2[2] = 3; array2[3] = 4; array2[4] = 5; //错误的写法 /*int [] array3 = new int[3] {1,2,3};*/ } }
2.2 一维数组元素的引用
通过角标的方式调用
//ArrayRef.java package com.ylaihui.array; public class ArrayRef { public static void main(String[] args) { String[] name = new String[3]; //2.如何调用数组的指定位置的元素:通过角标的方式调用。 //数组的角标(或索引)从0开始的,到 数组的长度-1 结束。 name[0] = "Jan"; name[1] = "Kan"; name[2] = "Han"; //name[3] = "Jan"; // ArrayIndexOutOfBoundsException System.out.println(name[1].charAt(0)); } }
2.3.数组的属性-长度
说明:
数组一旦初始化,其长度就是确定的。arr.length
数组长度一旦确定,就不可修改。
2.4.一维数组的遍历
for(int i = 0;i < names.length;i++){
System.out.println(names[i]);
}
//ArrayLength.java package com.ylaihui.array; public class ArrayLength { public static void main(String[] args) { //如何获取数组的长度。 //属性:length String[] names = new String[]{"Kon","Jon","Fon"}; // 遍历数组 names for (int i = 0; i < names.length; i++) { System.out.println(names[i]); } } }
2. 5 一维数组元素的默认初始化值
数组元素的默认初始化值
> 数组元素是整型:0 数组元素是 byte short int long 都是 0
> 数组元素是浮点型:0.0
> 数组元素是char型:0或'\u0000',而非'0', 是ascii码是0的字符,数值是0
> 数组元素是boolean型:false
> 数组元素是引用数据类型:null , 空值, 非 "null"
//ArrayElmtInitValue.java package com.ylaihui.array; public class ArrayElmtInitValue { public static void main(String[] args) { int[] arr1 = new int[4]; System.out.println(arr1[0]); // 0 short[] arr2 = new short[4]; System.out.println(arr2[0]); // 0 double[] arr3 = new double[4]; System.out.println(arr3[0]); // 0.0 char[] arr4 = new char[4]; System.out.println("[" + arr4[0] + "]"); // ascii的0 boolean[] arr5 = new boolean[4]; System.out.println(arr5[0]); // false String[] arr6 = new String[4]; System.out.println(arr6[0]); // 空值 null } }
3. JVM内存结构
方法中的变量都是局部变量, 存放在栈中。
new的对象、结构在堆中
arr1 = new String[3]; 后, 原来new的对象没有引用了, 会被垃圾回收器回收。
暂时还未讲到常量池,实际字符串常量是存放在常量池中的
4. 如何理解二维数组
Java 语言里提供了支持多维数组的语法。
如果说可以把一维数组当成几何中的线性图形,那么二维数组就相当于是一个表格,像右图Excel中的表格一样。
对于二维数组的理解,我们可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。其实, 从数组底层的运行机制来看,其实没有多维数组。
一维数组的元素可以是基本数据类型, 也可以是引用数据类型,
一维数组是引用数据类型
那么一维数组的元素可以是一维数组, 此时的数组就是二维数组。
4.1. 二维数组的声明与初始化
//ArraysInit.java package com.ylaihui.array; public class ArraysInit { public static void main(String[] args) { // 静态初始化 int[][] arr1 = new int[][]{{1,2,3},{4,5,6}}; // 动态初始化-方式1 int[][] arr2 = new int[2][]; // 动态初始化-方式2 int[][] arr3 = new int[2][3]; // 错误写法 -- 后面有初始化值,就不需要指定数组的长度了 // int[][] arr1 = new int[2][]{{1,2,3},{4,5,6}}; // int[][] arr1 = new int[2][3]{{1,2,3},{4,5,6}}; // 正确的写法 --不常用的,但是正确 int arr4[][] = new int[][]{{1,2,3},{4,5,6}}; int[] arr5[] = new int[][]{{1,2,3},{4,5,6}}; int[] arr6[] = {{1,2,3},{4,5,6}}; // 前面指定了int了, 后面只能是int了,可省略不写, 类型推断 } }
4.2 二维数组的使用
//ArraysRef.java package com.ylaihui.array; public class ArraysRef { public static void main(String[] args) { String[][] arr1 = new String[3][]; System.out.println(arr1[0]); // System.out.println(arr1[0][0]); // NullPointerException arr1[0] = new String[3]; System.out.println(arr1[0][0]); } }
4.3 遍历二维数组元素
有了一维数组的基础, 二维数组的遍历就容易了。
//ArraysLength.java package com.ylaihui.array; public class ArraysLength { public static void main(String[] args) { int[][] arr = new int[][]{{1,2,3,4},{1,2},{1,2,3,4,5}}; // arr.length 是外层数组的长度 // arr[i].length 是外层数组的每个元素的长度 for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { System.out.print(arr[i][j] + " "); } System.out.println(); } } }
4.4 二维数组的初始化值
针对于初始化方式一:比如:int[][] arr = new int[4][3];
外层元素的初始化值为:地址值 比如 [I@15db9742 其中 [ 表示一个一维数组,i表示int类型, @ 后的是地址值
内层元素的初始化值为:与一维数组初始化情况相同, arr[0][0] 为0
针对于初始化方式二:比如:int[][] arr = new int[4][];
外层元素的初始化值为:null
内层元素的初始化值为:不能调用,否则报错。
//ArraysMem.java package com.ylaihui.array; public class ArraysMem { public static void main(String[] args) { int[][] arr = new int[4][3]; System.out.println(arr[0]); // [I@15db9742 System.out.println(arr[0][0]); // 0 System.out.println(arr); // [[I@6d06d69c int[][] arr2 = new int[4][]; // null System.out.println(arr2[0]); // System.out.println(arr2[0][0]); // NullPointerException String[][] arr3 = new String[4][3]; System.out.println(arr3[0]); // [Ljava.lang.String;@7852e922 System.out.println(arr3[0][0]); // null } }
4.5 二维数组的内存解析
JVM中的内存结构
method area 方法区
stack: 局部变量
heap: new出来的
字符串 "HelloJava" 常量池中
static 静态域中
5. Arrays工具类的使用
//ArraysTest.java package com.ylaihui.array; import java.util.Arrays; public class ArraysTest { public static void main(String[] args) { int[] arr1 = new int[]{1,2,3,4}; int[] arr2 = new int[]{1,2,3,4}; //1.boolean equals(int[] a,int[] b):判断两个数组是否相等。 boolean bln = Arrays.equals(arr1, arr2); System.out.println(bln); // true //2.String toString(int[] a):输出数组信息。 System.out.println(Arrays.toString(arr1)); // [1, 2, 3, 4] //3.void fill(int[] a,int val):将指定值填充到数组之中。 Arrays.fill(arr1, 10); System.out.println(Arrays.toString(arr1)); //4.void sort(int[] a):对数组进行排序。 int[] arr3 = new int[]{1,3,2,-1,100}; Arrays.sort(arr3); System.out.println(Arrays.toString(arr3)); int[] arr4 = new int[]{-98,-34,2,34,54,66,79,105,210,333}; //5.int binarySearch(int[] a,int key) 二分查找, 返回负数,表示没找到 int index = Arrays.binarySearch(arr4, 210); if(index >= 0) { System.out.println(arr4[index]); }else{ System.out.println("not found"); } } }
6. 数组的常见异常
数组索引越界 ArrayIndexOutOfBoundsExcetion
空指针异常 NullPointerException
//ArrayExceptionTest.java package com.ylaihui.array; public class ArrayExceptionTest { public static void main(String[] args) { //1. 数组索引越界的异常: ArrayIndexOutOfBoundsExcetion int[] arr = new int[]{1,2,3,4,5}; // for(int i = 0;i <= arr.length;i++){ // System.out.println(arr[i]); // } // System.out.println(arr[-2]); // System.out.println("hello"); //2.2. 空指针异常: NullPointerException //情况一: // int[] arr1 = new int[]{1,2,3}; // arr1 = null; // System.out.println(arr1[0]); //情况二: // int[][] arr2 = new int[4][]; // System.out.println(arr2[0][0]); //情况三: String[] arr3 = new String[]{"AA","BB","CC"}; arr3[0] = null; System.out.println(arr3[0].toString()); } }
思考题
1.写出一维数组初始化的两种方式
2.写出二维数组初始化的两种方式
3.如何遍历如下的二维数组
4.不同类型的一维数组元素的默认初始化值各是多少
5.一维数组的内存解析
String[] strs = new String[5];
strs[2] = “Tom”;
strs = new String[3];
答案
写出一维数组初始化的两种方式
int[] arr = new int[5];//动态初始化
String[] arr1 = new String[]{"Tom","Jerry","Jim"};//静态初始化
数组一旦初始化,其长度就是确定的。arr.length
数组长度一旦确定,就不可修改。
2.写出二维数组初始化的两种方式
int[][] arr = new int[4][3];//动态初始化1
int[][] arr1 = new int[4][];//动态初始化2
int[][] arr2 = new int[][]{{1,2,3},{4,5,6},{7,8}};//静态初始化
3.如何遍历如下的二维数组
int[] arr = new int[][]{{1,2,3},{4,5},{6,7,8}};
for(int i = 0;i < arr.length;i++){
for(int j = 0;j < arr[i].length;j++){
System.out.print(arr[i][j] + "\t");
}
System.out.println();
}
4.不同类型的一维数组元素的默认初始化值各是多少
整型 : 0
浮点型:0.0
char:0
boolean :false
引用类型:null
5.一维数组的内存解析:
String[] strs = new String[5];
strs[2] = “Tom”;
strs = new String[3];