数组是什么?
数组的本质也是一个窗口,是一个可以装多个数据的容器。
数组就是一个数据类型一致、长度固定、内存空间连续的容器。
数组的分类
- 一维
- 多维
一维数组的基本操作
数组的定义
1. 方式一
-
格式:
数据类型[] 数组名 = new 数据类型[长度];
-
数组定义格式详解:
-
数据类型: 创建的数组容器可以存储什么数据类型,所有数据类型都可以存储。
-
[] : 表示数组。
-
数组名字:为定义的数组起个变量名,满足标识符规范,可以使用名字操作数组。
-
new:关键字,创建数组使用的关键字。
-
[长度]:数组的长度,表示数组容器中可以存储多少个元素。
-
注意:数组有定长特性,长度一旦指定,不可更改。
-
和水杯道理相同,买了一个2升的水杯,总容量就是2升,不能多也不能少。
-
-
-
举例:
定义可以存储6个整数的数组容器,代码如下:
int[] array = new int[6];
2.方式二
-
格式:
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...};
-
举例:
定义存储1,2,3,4,5,6整数的数组容器。
int[] arr = new int[]{1,2,3,4,5,6};
3.方式三
-
格式:
数据类型[] 数组名 = {元素1,元素2,元素3...};
-
举例:
定义存储1,2,3,4,5,6整数的数组容器。
int[] arr = {1,2,3,4,5,6};
数组的操作
数组的基本概念
索引:每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。
- 格式:
数组名[索引]
- 数组的长度属性:每个数组都具有长度,而且是固定的,Java中赋予了数组的一个属性,可以获取到数组的长度,语句为:数组名.length ,属性length的执行结果是数组的长度,int类型结果。由次可以推断出,数组的最大索引值为数组名.length-1。
数组的基本操作
向数组中添加数据
数组名[索引]=值;
将数组中的数据取出来
数组名[索引];
修改数组中的数据
数组名[索引]=值;
数组创建后,涉及到数组的对应位置元素的初始化、元素的修改、元素的获取。
public static void main(String[] args) {
// 定义一个定长数组
int[] array = new int[3];
// 1、元素赋值
array[0]=1;
array[1]=2;
array[2]=3;
// 2、元素修改
array[0]=11;
// 3、元素获取
int a=array[0];
// 打印数组,Arrays先了解即可
System.out.println(Arrays.toString(array));
}
二维数组的定义
二维数组,本质就是在一维数组的基础上,每一个元素又由一个新的数组组成。
1. 方式一
- 格式:
数据类型[][] 数组名字 = new 数据类型[长度][长度];
- 举例:
int[][] array = new int[2][3];
这种方式只是设定了数组的一维和二维的长度,并没有赋值。
2.方式二
- 格式:
数据类型[][] 数组名字 = new 数据类型[长度][];
- 举例:
int[][] array = new int[2][];
这种方式在定义的时候只规定了外层的一维数组个数,并未规定内部元素嵌套的二维数组的内容和长度。
3.方式三
- 格式:
数据类型[][] 数组名字 = new 数据类型[][]{{元素1},{元素2}...};
或者
数据类型[][] 数组名字 = {{元素1},{元素2}...};
- 举例:
int[][] array = new int[][]{{1,2},{3,4}};
int[][] array = {{1,2},{3,4}};
这种方式在定义的时候,直接对数组进行了初始化赋值。
二维数组的基本操作
二维数组同样,涉及到赋值、修改与获取。
public static void main(String[] args) {
// 定义一个指定容量的二维数组
int[][] array = new int[2][3];
// 1、赋值
array[0][0]=0;
array[0][1]=1;
array[0][2]=2;
array[1][0]=3;
array[1][1]=4;
// 2、修改
array[0][0]=110;
// 3、获取
int a=array[0][0];
// 打印数组
System.out.println(Arrays.deepToString(array));
}
数组的初始值
数组创建后默认是有初始值,整数为0,小数0.0,字符为空字符,boolean为false,引用为null。
数组的遍历
//1.普通for循环遍历
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
//2.foreach循环
for (int num : arr) {
System.out.println(num);
}
数组内存分析
在方法中的变量都叫局部变量
这种方式在定义的时候,直接对数组进行了初始化赋值。
Java虚拟机的内存划分
内存区域说明:
区域名称 | 作用 | 说明 |
---|---|---|
程序计数器(寄存器) | 是一块较小的内存区域,可以看做是当前线程执行的字节码的行号指示器 | 给CPU使用,和我们开发无关 |
虚拟机栈 | 虚拟机栈描述的是Java方法执行的内存模型 | JVM在使用操作系统功能的时候使用,和我们开发无关 |
堆 | 该区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存 | 是Java虚拟机所管理的内存中最大的一块,被进程的所有线程共享,在虚拟机启动时被创建 |
方法区 | 存放的是被虚拟机加载的class类信息,常量,静态变量,即时编译器编译后的代码等数据 | 方法区也是线程共享的 |
本地方法栈 | 与虚拟机栈类似,为虚拟机使用到的Native方法服务 | 方法运行时使用的内存,比如main方法运行,进入方法栈中执行 |
数组的排序
- 冒泡排序
- 选择排序
- 插入排序
- 快速排序
冒泡排序
因排序算法的过程像河水中的气泡向上冒的过程,因为取名为冒泡排序。
冒泡排序是两相邻的数对比。写排序算法主要得弄清楚外层循环次数和内层循环的规律。当2层循环写出来后,剩下的就是相邻两数对比、交换的过程了。
public static void main(String[] args) {
// 定义一个元素顺序杂乱的数组
int[] arr = { 4, 1, 3, 6, 2, 5};
// 外层循环表示比较轮数
for (int i = 1; i <= arr.length-1; i++) {
// 内层循环对比相邻两个数
for (int j = 0; j < arr.length-i; j++) {
// 定义一个临时变量
int tempMax=0;
// 进行元素位置交换
if(arr[j]>arr[j+1]) {
tempMax=arr[j];
arr[j]=arr[j+1];
arr[j+1]=tempMax;
}
}
}
// 打印
System.out.println(Arrays.toString(arr));
}
选择排序
public static void main(String[] args) {
// 定义一个元素顺序杂乱的数组
int[] arr = { 4, 1, 3, 6, 2, 5};
// 外层循环表示比较轮数
for (int i = 0; i < arr.length - 1; i++) {
//内层循环对比次数
for (int j = i+1; j <arr.length ; j++) {
// 定义一个临时变量
int tempMin=0;
// 进行元素位置交换
if(arr[i]>arr[j]) {
tempMin=arr[i];
arr[i]=arr[j];
arr[j]=tempMin;
}
}
}
// 打印
System.out.println(Arrays.toString(arr));
}
插入排序
public static void main(String[] args) {
// 定义一个元素顺序杂乱的数组
int[] arr = { 4, 1, 3, 0, 2, 5};
// 外层循环表示比较轮数
for (int i = 1; i <arr.length ; i++) {
int n=i; //插入的位置
//内层循环对比次数
while (n>0 && arr[n]<arr[n-1]){
// 定义一个临时变量
int tempMax=0;
//进行元素位置交换
tempMax=arr[n];
arr[n]=arr[n-1];
arr[n-1]=tempMax;
n--;
}
}
//打印
System.out.println(Arrays.toString(arr));
}
快速排序
快排比较麻烦,这里就不详细说明了
Arrays数组工具类
上一章,我们通过底层原始方式对数组完成了相关的遍历、排序、查找等操作,如果以后还有这种需求,我们再重复编写这种代码就显得比较麻烦,因此,我们可以自己把这些实现封装成一个工具类。鉴于此,Java为了方便开发,也提供了专门针对数组操作的工具类Arrays,这里面提供了很多实用方法,下面对这里一些常用方法进行介绍。
常用Arrays工具类方法介绍:
方法 | 说明 |
---|---|
toString(Object[] a) | 将任意类型的数组的元素以字符串形式打印 |
deepToString(Object[] a) | 将任意类型的数组的深度元素以字符串形式打印(比如多维数组元素) |
asList(T... a) | 将任意类型数组转换为List集合形式 |
binarySearch(int[] a, int key) | 二分查找方法 |
sort(int[] a) | 数组排序 |
fill(int[] a, int fromIndex, int toIndex, int val) | 替换数组指定角标位置元素 |
copyOfRange(int[] original, int from, int to) | 对原数组进行指定范围元素复制为一个新数组 |
public static void main(String[] args) {
// 定义一个元素顺序杂乱的数组
int[] arr = { 4, 1, 3, 6, 2, 5};
// 直接打印
System.out.println(arr);
// 1、将数组以字符串形式打印
System.out.println(Arrays.toString(arr));
// 2、数组排序
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
// 3、数组二分查找
int index =Arrays.binarySearch(arr, 1);
System.out.println("元素1在有序数组arr中的索引位置为:"+index);
// 4、数组元素替换
Arrays.fill(arr, 0, 2, 0);
System.out.println(Arrays.toString(arr));
// 5、数组的复制
int[] copyArray =Arrays.copyOfRange(arr, 0, 3);
System.out.println(Arrays.toString(copyArray));
}