数组概述
概念: 数组就是用于存储数据的长度固定的容器,保证多个数据的数据类型要一致。
容器概念
百度百科中对数组的定义:
数组(array),就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,以便统一管理他们,然后用编号区分他们,这个名字称为数组名,编号称为下标或索引(index)。组成数组的各个变量称为数组的元素(element)。数组中元素的个数称为数组的长度(length)。
数组的特点:
数组的声明
实例
String[] strings; // 推荐
char chars[]; // 不推荐
一维数组的初始化
格式一:
实例
/*
声明int类型的数组,数组名为ages,
同时初始化,数组中的元素为1, 2, 3, 4, 5
*/
int[] ages = new int[]{1, 2, 3, 4, 5};
?我们可以先声明数组,之后单独初始化
double[] scores; //声明double类型的数组,数组名称为scores
scores = new double[]{1, 2, 3, 4, 5};//数组初始化,数组的元素为1, 2, 3, 4, 5
格式二:
这种格式化,只能声明数组的同时完成初始化,不能分开进行?
实例
/*
声明int类型的数组,数组名为arr,
同时初始化,数组中的元素为1, 2, 3, 4, 5
*/
int[] arr = {1, 2, 3, 4, 5};
double[] scores; //声明数组
// scores = {1, 2, 3, 4, 5}; 错误:必须在一个语句中完成,不能分开两个语句写
?格式三:
实例
/*
声明int类型的数组,数组名为array,
同时,并且初始化。数组元素为默认值
*/
int[] array = new int[4];
我们可以先声明数组,之后单独初始化
实例
//声明int类型的数组,数组名为array
int[] array;
//数组初始化,数组元素为默认值
array= new int[4];
数组定义格式详解:
注意:数组有定长特性,长度一旦指定,不可更改。和水杯道理相同,买了一个2升的水杯,总容量就是2升,不能多也不能少。
总结:
数组的默认值
当我们使用动态初始化创建数组的时候,此时只确定了数组的长度,没有明确指明数组中的元素。此时数组中的元素会被赋上默认值。不同的数组类型,默认值也不同,具体如下图所示
元素的访问
索引访问数组中的元素:
实例
public class Demo {
public static void main(String[] args) {
//定义存储int类型数组,赋值元素1,2,3,4,5
int[] arr = {1, 2, 3, 4, 5};
//为0索引元素赋值为6
arr[0] = 6;
//获取数组0索引上的元素
int i = arr[0];
System.out.println(i);
//直接输出数组0索引元素
System.out.println(arr[0]);
}
}
数组的遍历
数组的长度属性: 每个数组都具有长度,而且是固定的,Java中赋予了数组的一个属性,可以获取到数组的长度,语句为:数组名.length,属性length的执行结果是数组的长度,int类型结果。由次可以推断出,数组的最大索引值为数组名.length-1
数组遍历: 就是将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基石
实例
public class Demo02Test {
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3, 4, 5};
//打印数组的属性,输出结果是5
System.out.println("数组的长度:" + arr.length);
//遍历输出数组中的元素
System.out.println("数组的元素有:");
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
数组内存图
Java虚拟机要运行程序,必须要对内存进行空间的分配和管理。 为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
内存详解:
数组在内存中的存储
下面代码在内存中的变化,如图所示
public class Demo {
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr);//[I@5f150435
}
}
小练习
import java.util.Arrays;
// 数组之冒泡排序(Bubble Sort)
public class Demo08Test {
public static void main(String[] args) {
//方式一
int [] arr = {10,20,30,-1111,-2,-10,10220,66};
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-1-i; j++) {
if (arr[j] >arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(arr)); //[-1111, -10, -2, 10, 20, 30, 66, 10220]
//方式二
arr =new int[] {10,20,30,-1111,-2,-10,10220,66};
for (int i = 0; i < arr.length-1; i++) {
boolean flag = true;
for (int j = 0; j < arr.length-1-i; j++) {
if (arr[j] >arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = false;
}
}
if (flag){
break;
}
}
System.out.println(Arrays.toString(arr));// [-1111, -10, -2, 10, 20, 30, 66, 10220]
}
}
什么是二维数组?本质上就是元素为一维数组的一个数组。二维数组的长度 指的是 数组内一维数组的个数,n维数组 存储的元素 是 n-1 维数组
int[][] arr; //arr是一个二维数组,可以看成元素是int[]一维数组类型的一个数组
二维数组的声明
格式:
//推荐
元素的数据类型[][] 二维数组的名称;
//不推荐
元素的数据类型 二维数组名[][];
//不推荐
元素的数据类型[] 二维数组名[];
实例
int[] x, y[]; //x是一维数组,y是二维数组
如果是静态初始化,右边new 数据类型[][]中不能写数字,因为行数和列数,由{}的元素个数决定
/*
方式一: 数据类型[][] 标识符 = {{一维数组的元素},{一维数组的的元素},{一维数组的元素}};
*/
int[][] arr = {{10,20},{30,40}};
也可以使用下面这种方式
/*
方式二: 数据类型[][] 标识符 = new 数据类型[][]{{一维数组的元素},{一维数组的元素}};
*/
double [][] doubleArr = new double[][]{{3.14,3.45},{6.78,9.78},{10.9}};
数组的动态初始化
确定行数和列数
/*
1.动态初始化方式一:
数据类型[][] 标识符 = new 数据类型[容量1][容量2];
容量1:代表此二维数组内 有多少一维数组
容量2:带表一维数组内 有多少个元素
*/
int [][] arr = new int[5][6];
此时创建完数组,行数、列数确定,而且元素也都有默认值,或者我们可以先确定有多少个一维数组,以后在指定每个一维数组中有多少元素
/*
动态初始化方式二:
数据类型[][] 标识符 = new 数据类型[容量1][];
注意事项:使用前 需要给每一个一维数组进行手动指定大小
*/
double [][] doubleArr = new double[3][];
常见的二维数组操作
获取二维数组中一维数组的个数
int [][] arr = new int[5][6];
// 二维数组名.length
System.out.println(arr.length); // 5
获取二维数组的某一个一维数组
int [][] arr = new int[5][6];
// 二维数组名[行下标] ,行下标的范围:[0, 二维数组名.length-1]
System.out.println(arr[1]);
获取二维数组的某一个一维数组的元素个数
int [][] arr = new int[5][6];
//二维数组名[行下标].length
System.out.println(arr[0].length);//6
获取二维数组的某一个一维数组的具体元素
int [][] arr = new int[5][6];
//二维数组名[行下标][列下标]
System.out.println(arr[0][0]);//0
二维数组的遍历
public class Demo{
public static void main(String[] args) {
String[][] strArr = {{"蔡旭坤", "特朗普"}, {"杨幂", "高圆圆"}, {"胡歌", "彭于晏", "吴彦祖"}};
//普通for循环
for (int i = 0; i < strArr.length; i++) {
for (int j = 0; j < strArr[i].length; j++) {
System.out.print(strArr[i][j] + "\t");
}
System.out.println();
}
System.out.println("=========================");
//增强for循环
for (String[] strings : strArr) {
for (String s : strings) {
System.out.print(s + "\t");
}
System.out.println();
}
}
}
数组越界异常
我们访问数组中不存在的索引,程序运行后,将会抛出 ArrayIndexOutOfBoundsException
数组越界异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改我们编写的代码。
int[] arr = {1,2,3};
System.out.println(arr[3]);
数组的每一行还未分配具体存储元素的空间,此时arr[0]是null,此时访问arr[0][0]会抛出NullPointerException 空指针异常。
//定义数组
int[][] arr = new int[3][];
System.out.println(arr[0][0]);//NullPointerException
小练习
/*
输出下面图形
1
2 2
3 3 3
4 4 4 4
5 5 5 5 5
*/
public class Demo04Test {
public static void main(String[] args) {
int[][] arr = new int[5][];
for (int i = 0; i < 5; i++) {
arr[i] = new int[i + 1];
for (int j = 0; j < arr[i].length; j++) {
arr[i][j] = i + 1;
}
}
//遍历
for (int[] ints : arr) {
for (int i : ints) {
System.out.print(i + "\t");
}
System.out.println();
}
}
}
注意事项:
二维数组中存储的是每个一维数组中的地址值