文章目录
- [一. 数组的基本概念](#一. 数组的基本概念)
-
- [1.1 为什么要使用数组?](#1.1 为什么要使用数组?)
- [1.2 什么是数组?](#1.2 什么是数组?)
- [1.3 数组的使用](#1.3 数组的使用)
- [二. 数组是引用类型](#二. 数组是引用类型)
- [三. 数组的应用场景](#三. 数组的应用场景)
- [四. 数组中的常用方法](#四. 数组中的常用方法)
- [五. 二维数组](#五. 二维数组)
一. 数组的基本概念
1.1 为什么要使用数组?
想象这样的一个场景:期末考试完后,老师要将所有学生的成绩保存起来,用我们学过的知识该怎么办呢? 可能是创建多个变量,每个变量用来存储一个学生的成绩,即:
java
public static void main(String[] args) {
int score1 = 70;
int score2 = 70;
int score3 = 70;
int score4 = 70;
int score5 = 70;
int score6 = 70;
int score7 = 70;
}
这样写就会遇到一个问题:数据量非常大的时候,创建的变量太多,代码太繁琐,不适用。
所以,我们就需要引入一个新的东西来存储信息---这就是数组。他使用起来非常简便,即:
java
int[] array = {70,70,70,70,70,70,70};
1.2 什么是数组?
数组:可以看成是相同类型元素的一个集合 (就像上面的学生成绩一样,都是int型)
数组在内存中则是一段连续的空间。每一小块空间都有自己的编号,存放一个数据。
1.3 数组的使用
1.3.1 数组的创建
T[] 数组名 = new T[N]
T:表示数组中存放元素的类型
N:表示数组的长度
1.3.2 数组的初始化
-
动态初始化:在创建数组时直接指定数组中元素的个数,但是可以灵活添加需要的元素。
int[] array = new int[10];
-
静态初始化:在创建数组时不直接指定数组元素的个数,而直接将具体的数据内容进行指定。
java
int[] array = {1,2,3,4,5,6,7,8,9,10};
int[] array1 = new int[]{1,2,3,4,5,6,7,8,9,10};
注:
- 静态初始化虽然没有指定数组的长度,但编译器在编译过程中会根据{}里元素的个数来确定数组的长度。
- 静态初始化时{}里的元素类型必须与[]里的数据类型一致。
- 如果数组已经开辟了内存空间,但是没有添加元素,则数组元素有其默认值。
如果是基本数据类型,则默认值为:
如果是引用类型,则默认值为:null
1.3.3 数组的使用
- 数组中元素的访问 :
数组在内存中是一段连续的空间,空间的编号都是从0开始,依次递增,该编号称为数组的下 标。数组可以通过下标访问任意位置的元素。
java
int[] array = {1,2,3,4,5,6,7,8,9,10};
int num1 = array[0];
int num2 = array[1];
int num3 = array[2];
注: 数组下标从0开始,介于[0,N)之间 不包括N(N为元素个数),不能越界,否则会出现数组下标越界的异常(上面是异常?后面会进行介绍)
- 遍历数组
遍历是指:把数组中的每个元素都访问一遍。
for循环遍历
java
int[] array = {1,2,3,4,5,6,7,8,9,10};
for (int i = 0; i < array.length; i++){
System.out.println(array[i]);
}
for-each遍历
java
int[] array = {1,2,3,4,5,6,7,8,9,10};
for (int a : array) {
System.out.println(a);
}
二. 数组是引用类型
基本数据类型创建的变量,称为基本变量,其空间中存放的是其对应的值。
引用数据类型创建的变量,称为对象的引用,其空间中存放的是其所指对象所在空间的地址。
注:
- 引用变量并不直接存储对象本身,可以简单理解成:对象在空间中的起始地址,通过该地址引用变量就可以去操作对象。
- null在Java中表示"空引用",也就是一个不指向对象的引用,表示一个无效的内存地址。
三. 数组的应用场景
1.1 保存数据
java
int[] array = {1,2,3,4,5,6,7,8,9,10};
1.2 作为函数的参数
java
public static void func(int[] arr){
System.out.println(arr.length);
}
public static void main(String[] args) {
int[] arr = {1,2,3};
func(arr);
}
1.3 作为函数的返回值
java
public static int[] setValue(int[] arr){
for (int i = 0; i < arr.length; i++){
arr[i] = i;
}
return arr;
}
public static void main(String[] args) {
int[] arr = new int[5];
int[] ret = setValue(arr);
}
四. 数组中的常用方法
4.1 数组转字符串 Arrays.toString()
java
int[] arr = {1,2,3};
System.out.println(Arrays.toString(arr));
4.2 数组拷贝
4.2.1 Arrays.copyOf()
java
int[] arr = {1,2,3};
int[] newArr = Arrays.copyOf(arr,arr.length);
4.2.2 Arrays.copyOfRange()
java
int[] arr = {1,2,3};
int[] newArr = Arrays.copyOfRange(arr,0,2);
4.2.3 System.arraycopy()
java
int[] arr = {1,2,3};
int[] newArr = new int[3];
System.arraycopy(arr,0,newArr,0,3);
4.2.4 arr.clone()
java
int[] arr = {1,2,3};
int[] newArr = arr.clone();
深拷贝、浅拷贝?
深拷贝 :如果我们能够做到修改拷贝之后的数组而不影响原数组,这样的拷贝叫做深拷贝。
浅拷贝 :如果我们不能够做到修改拷贝之后的数组而不影响原数组,或者说如果我们修改拷贝后的数组会影响到原数组,这样的拷贝叫做浅拷贝。
4.3 数组排序 Arrays.sort()
给定一个数组, 让数组升序 (降序) 排序.
java
int[] arr = {1,2,3};
Arrays.sort(arr);
4.4 数组逆序
思路:设置俩个下标,前一个下标指向数组第一个元素,后一个下标指向数组最后一个元素,然后交换这俩个元素, 再让 前一个下标+1 后一个下标-1 重新进入循环。
java
public static void reverse(int[] arr){
int left = 0;
int right = arr.length-1;
while (left < right){
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7,8,9,10};
reverse(arr);
System.out.println(Arrays.toString(arr));
}
4.5 求数组中元素的平均值
思路:将数组内元素全部求和 再除以元素个数
java
public static int avg(int[] arr){
int sum = 0;
for (int i = 0; i < arr.length; i++){
sum += arr[i];
}
return sum / arr.length;
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7,8,9,10};
int ret = avg(arr);
System.out.println(ret);
}
4.6 查找数组中指定元素
- 顺序查找:遍历数组
java
public static void find(int[] arr,int key){
for (int i = 0; i < arr.length; i++){
if (arr[i] != key){
continue;
}else {
break;
}
}
System.out.println("找到了");
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7,8,9,10};
find(arr,5);
}
- 二分查找:
思路:前提 数组必须有序
将数组最中间元素与要查询的元素比较大小:
如果相等,则找到了 返回即可。
如果小于,则在数组的右半边以相同方式继续查找。
如果大于,则在数组的左半边以相同方式继续查找。
java
public static void binarySearch(int[] arr, int key){
int left = 0;
int right = arr.length-1;
while (left < right){
int mid = (left + right) / 2;
if (arr[mid] < key){
left = mid + 1;
}else if (arr[mid] > key){
right = mid - 1;
}else {
System.out.println("找到了");
break;
}
}
if (left >= right){
System.out.println("没找到");
}
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7,8,9,10};
binarySearch(arr,5);
}
五. 二维数组
基本语法:数据类型[][] 数组名称 = new 数据类型[行数][列数];
5.1 二维数组的初始化
二维数组的初始化方式和一维数组类似,共有两类。
注:必须有行数,可以没有列数;
5.1.1 动态初始化
java
int[][] arr = new int[2][3];
5.1.2 静态初始化
java
int[][] arr = {{1,2,3},{4,5,6}};
int[][] arr1 = new int[][]{{1,2,3},{4,5,6}};
5.2 二维数组的访问
二维数组实际上是两个一维数组的组合,每个一维数组都是这个二维数组的每一行。
5.2.1 for循环
java
int[][] arr = {{1,2,3},{4,5,6}};
for (int i = 0; i < arr.length; i++){ // arr.length 得到二维数组有几行
for (int j = 0; j < arr[0].length; j++){ // arr[].length 得到二维数组有几列
System.out.println(arr[i][j]);
}
}
5.2.2 for-each
java
int[][] arr = {{1,2,3},{4,5,6}};
for(int[] array : arr){ //得到二维数组的每一行
for (int x : array){ //得到二维数组的每一列
System.out.println(x);
}
}
5.2.3 库函数 Arrays.deepToString()
java
int[][] arr = {{1,2,3},{4,5,6}};
System.out.println(Arrays.deepToString(arr));
5.3 不规则数组
java
//行数确定时 可以根据行数来设置不同的列数
int[][] arr = new int[2][];
arr[0] = new int[3];
arr[1] = new int[5];
System.out.println(Arrays.deepToString(arr));
//打印结果:[{0,0,0},{0,0,0,0,0}] 因为没有赋值 所以都设置默认值0