1、数组的介绍
数组(Array):就是多个相同类型的数据按照一定的顺序排列的集合。简单理解数组就是一个数据容器。
数组是编程中最常见的一种数据结构,可用于存储多个数据,每个数组元素存放一个数据,通常我们可以通过数组元素的索引来访问数组元素。包括为数组元素赋值和取出数组元素的值。
数组的相关概念:数组名
,下标(或脚标、索引)(index)
,元素(element)
,数组的长度(length)
。
数组的基本特性:
- ①、数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
- ②、创建数组对象会在内存中开辟一整块连续的空间,而数组的引用是这块连续空间的首地址。
- ③、数组一旦初始化完成,数组在内存所占用的空间将被固定下来,因此数组的长度不可变。
- ④、数组可以直接通过下标的方式来调用,下标从0开始。
2、数组的声明与初始化
①、数组的声明
注:数组在使用之前需要先进行声明并初始化
2.1、数组的声明
数组的声明比较简单,和变量基本一样,只是多了个括号[]
。数组的声明如下:
//推荐
元素的数据类型[] 数组的名称;
int[] age;
//不推荐
元素的数据类型 数组名[];
int age[];
2.2、数组的初始化
数组使用之前需要先初始化,什么是数组初始化?就是给数组分配内存空间,并给元素赋值。数组的初始化有两种:静态初始化
和动态初始化
。
①、静态初始化:定义数组的同时为数组分配内存空间,并赋值。程序员只给定数组元素的初始值,不指定数组长度,由系统决定数组的长度。
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...};
或
数据类型[] 数组名;
数组名 = new 数据类型[]{元素1,元素2,元素3...};
简化方式:
数据类型[] 数组名 = {元素1,元素2,元素3...};//必须在一个语句中完成,不能分开两个语句写
②、动态初始化:初始化时候程序员只指定数组长度,由系统元素分配初始值(为对应类型的默认值,比如int默认赋值为0)。
数据类型 [ ] 数组名称 = new 数据类型 [数组长度]
或
数据类型 数组名称[ ] = new 数据类型 [数组长度]
③、简单举例代码如下:
//声明一个元素为1,2,3的int型数组
int[] arr=new int[]{1,2,3};
int[] arr1={1,2,3};
//声明一个长度为3的数组
int[] arr2=new int[3];
④、错误写法:
//未指定数组长度
int [] arr1=new int[];
//数组前面[]不能写长度
int [5] arr2=new int[5];
//静态初始化不能写长度
int [] arr3=new int[3]{1,2,3};
上面的代码写法都是错误的,在编译时会报错。
3、数组元素的访问与遍历
①、访问数组元素以及给数组元素赋值
数组是存在下标索引的,索引的范围为[0,数组的length-1]
,通过下标可以获取指定位置的元素,数组下标是从0开始的,也就是说下标0对应的就是数组中第1个元素,可以很方便的对数组中的元素进行存取操作。格式为:数组名[索引]
。
//声明一个长度为3的数组
int[] arr=new int[3];
//给arr第1个元素赋值1
arr[0]=1;
//给arr第2个元素赋值2
arr[1]=2;
//输出
System.out.println(arr[0]);
System.out.println(arr[1]);
上面的arr数组,我们只能赋值三个元素,也就是下标从0到2,如果你访问 arr[3] ,那么会报数组下标越界异常。
②、数组的遍历
数组遍历: 就是将数组中的每个元素分别获取出来,这就是遍历。遍历也是数组操作中的基石,数组有个 length 属性,是记录数组的长度的,我们可以利用length属性来遍历数组。语句为:数组名.length
,返回int类型结果。由次可以推断出,数组的最大索引值为数组名.length-1
。
//声明一个元素为1,2,3的int型数组
int[] arr=new int[]{1,2,3};
//遍历arr数组
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
// 使用增强for循环foreach进行遍历
for (int i : arr) {
System.out.println(i);
}
//使用Arrays.toSting(数组名)进行遍历
System.out.println(Arrays.toString(arr));
4、数组的内存图
众所周知,程序是运行在内存中的,而Java程序是运行在Java虚拟机(JVM)上的,那么JVM要运行程序,必须要对内存进行空间的分配和管理。JVM的内存是怎么划分的呢?为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
数组内存图分析:
public static void main(String[] args) {
int[] arr = new int[3];
int[] arr2 = new int[2];
System.out.println(arr);
System.out.println(arr2);
}
5、数组的使用举例
①、将数组元素反转:
public class ArrayTest {
public static void main(String[] args) {
String[] str=new String[]{"AA","BB","CC","DD","EE","FF","GG"};
System.out.println("反转前:");
for (int i = 0; i < str.length; i++) {
System.out.print(str[i]+"\t");
}
for(int i=0;i<str.length/2;i++){
String temp=str[i];
str[i]=str[str.length-i-1];
str[str.length-i-1]=temp;
}
System.out.println();
System.out.println("反转后:");
for (int i = 0; i < str.length; i++) {
System.out.print(str[i]+"\t");
}
}
}
②、线性查找:
public class ArrayTest1 {
public static void main(String[] args) {
String[] str=new String[]{"AA","BB","CC","DD","EE","FF","GG"};
String dest="BB";
boolean isFlag=true;
for (int i = 0; i < str.length; i++) {
if (dest.equals(str[i])){
System.out.println("找到了元素,位置在"+(i+1));
isFlag=false;
break;
}
}
if (isFlag) {
System.out.println("对不起,没有找到");
}
}
}
③、提到数组都离不开一个经典的排序——冒泡排序
public class ArrayTest2 {
public static void main(String[] args) {
int[] arr=new int[]{56,12,32,98,78,45,-45,3,55,-16};
for (int i = 0; i < arr.length; 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;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+"\t");
}
}
}
数组无论在Java,C,C++,PHP等语言中都有着非常重要的地位,所以学号数组基础非常有必要。
6、二维数组(理解)
二维数组:本质上就是数组的元素为一维数组的一个数组。意思就是一个一维数组存储的是另一个数组的地址值,而另一个数组才是真正用来存储值的。
6.1、二维数组的声明
声明语法格式为:
//推荐
元素的数据类型[][] 二维数组的名称;
//不推荐
元素的数据类型 二维数组名[][];
//不推荐
元素的数据类型[] 二维数组名[];
//声明一个二维数组
int[][] arr;
6.2、二维数组的初始化
①、静态初始化,程序员给定元素初始值,由系统决定数组长度。
//1.先声明,再静态初始化
元素的数据类型[][] 二维数组名;
二维数组名 = new 元素的数据类型[][]{
{元素1,元素2,元素3 。。。},
{第二行的值列表},
...
{第n行的值列表}
};
//2.声明并同时静态初始化
元素的数据类型[][] 二维数组名 = new 元素的数据类型[][]{
{元素1,元素2,元素3 。。。},
{第二行的值列表},
...
{第n行的值列表}
};
//3.声明并同时静态初始化的简化写法
元素的数据类型[][] 二维数组名 = {
{元素1,元素2,元素3 。。。},
{第二行的值列表},
...
{第n行的值列表}
};
如果是静态初始化,右边new 数据类型[][]中不能写数字,因为行数和列数,由{}的元素个数决定
简单的示例:
//声明二维数组
int[][] arr;
//静态初始化
arr = new int[][]{{1,2,3},{4,5,6},{7,8,9}};
//arr = new int[3][3]{{1,2,3},{4,5,6},{7,8,9}};//错误,静态初始化,右边new 数据类型[]中不能指定长度
//声明并同时初始化
int[][] arr = new int[][]{{1,2,3},{4,5,6},{7,8,9}};
//声明并同时初始化的简化写法
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};//声明与初始化必须在一句完成
public static void main(String[] args) {
//定义数组
int[][] arr = {{1,2,3},{4,5},{6}};
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[0][0]); //1
System.out.println(arr[1][0]); //4
System.out.println(arr[2][0]); //6
System.out.println(arr[0][1]); //2
System.out.println(arr[1][1]); //5
//越界
System.out.println(arr[2][1]); //错误
}
②、动态初始化(规则二维表)程序员指定数组的长度,后期再赋值(系统会先给定元素默认初始值)。
什么是规则二维表?规则二维表的每一行的列数是相同的。
//(1)确定行数和列数
元素的数据类型[][] 二维数组名 = new 元素的数据类型[m][n];
m:表示这个二维数组有多少个一维数组。或者说一共二维表有几行
n:表示每一个一维数组的元素有多少个。或者说每一行共有一个单元格
//此时创建完数组,行数、列数确定,而且元素也都有默认值
//(2)再为元素赋新值
二维数组名[行下标][列下标] = 值;
public static void main(String[] args) {
//定义一个二维数组
int[][] arr = new int[3][2];
//定义了一个二维数组arr
//这个二维数组有3个一维数组的元素
//每一个一维数组有2个元素
//输出二维数组名称
System.out.println(arr); //地址值 [[I@175078b
//输出二维数组的第一个元素一维数组的名称
System.out.println(arr[0]); //地址值 [I@42552c
System.out.println(arr[1]); //地址值 [I@e5bbd6
System.out.println(arr[2]); //地址值 [I@8ee016
//输出二维数组的元素
System.out.println(arr[0][0]); //0
System.out.println(arr[0][1]); //0
}
③、动态初始化(不规则二维表);不规则二维表:每一行的列数可能不一样。
//(1)先确定总行数
元素的数据类型[][] 二维数组名 = new 元素的数据类型[总行数][];
//此时只是确定了总行数,每一行里面现在是null
//(2)再确定每一行的列数,创建每一行的一维数组
二维数组名[行下标] = new 元素的数据类型[该行的总列数];
//此时已经new完的行的元素就有默认值了,没有new的行还是null
//(3)再为元素赋值
二维数组名[行下标][列下标] = 值;
public static void main(String[] args) {
//定义数组
int[][] arr = new int[3][];
System.out.println(arr); //[[I@175078b
System.out.println(arr[1][0]);//NullPointerException
System.out.println(arr[0]); //null
System.out.println(arr[1]); //null
System.out.println(arr[2]); //null
//动态的为每一个一维数组分配空间
arr[0] = new int[2];
arr[1] = new int[3];
arr[2] = new int[1];
System.out.println(arr[0]); //[I@42552c
System.out.println(arr[1]); //[I@e5bbd6
System.out.println(arr[2]); //[I@8ee016
System.out.println(arr[0][0]); //0
System.out.println(arr[0][1]); //0
//ArrayIndexOutOfBoundsException
//System.out.println(arr[0][2]); //错误
arr[1][0] = 100;
arr[1][2] = 200;
}
6.3、二维数组的遍历(两个for循环)
for(int i=0; i<二维数组名.length; i++){
for(int j=0; j<二维数组名[i].length; j++){
System.out.print(二维数组名[i][j]);
}
System.out.println();
}
6.4、二维数组的内存图分析
int[][] arr = {{1},{2,2},{3,3,3},{4,4,4,4},{5,5,5,5,5}};
7、数组的工具类
在java.util包下提供了一个叫Arrays
的工具类,里面提供了很多静态方法来对数组进行操作,而且如下每一个方法都有各种重载形式,以下只列出int[]
类型的,其他类型的数组类推:
- static int binarySearch(int[] a, int key) :要求数组有序,在数组中查找key是否存在,如果存在返回第一次找到的下标,不存在返回负数
- static int[] copyOf(int[] original, int newLength) :根据original原数组复制一个长度为newLength的新数组,并返回新数组
- static int[] copyOfRange(int[] original, int from, int to) :复制original原数组的[from,to)构成新数组,并返回新数组
- static boolean equals(int[] a, int[] a2) :比较两个数组的长度、元素是否完全相同
- static void fill(int[] a, int val) :用val填充整个a数组
- static void fill(int[] a, int fromIndex, int toIndex, int val):将a数组[fromIndex,toIndex)部分填充为val
- static void sort(int[] a) :将a数组按照从小到大进行排序
- static void sort(int[] a, int fromIndex, int toIndex) :将a数组的[fromIndex, toIndex)部分按照升序排列
- static String toString(int[] a) :把a数组的元素,拼接为一个字符串,形式为:[元素1,元素2,元素3。。。]
示例代码:
import java.util.Arrays;
import java.util.Random;
public class Test {
public static void main(String[] args) {
int[] arr = new int[5];
//1、打印数组,输出地址值
System.out.println(arr); // [I@2ac1fdc4
//2、toString;数组内容转为字符串
System.out.println("arr数组初始状态:" + Arrays.toString(arr));
//3、fill
Arrays.fill(arr, 3);
System.out.println("arr数组现在状态:" + Arrays.toString(arr));
//赋值操作
Random rand = new Random();
for (int i = 0; i < arr.length; i++) {
arr[i] = rand.nextInt(100);//赋值为100以内的随机整数
}
System.out.println("arr数组现在状态:" + Arrays.toString(arr));
//4、copyOf
int[] arr2 = Arrays.copyOf(arr, 10);
System.out.println("新数组:" + Arrays.toString(arr2));
//5、equals
System.out.println("两个数组的比较结果:" + Arrays.equals(arr, arr2));
//6、sort
Arrays.sort(arr);
System.out.println("arr数组现在状态:" + Arrays.toString(arr));
}
}