阿里云【名师课堂】Java面向对象开发10 ~ 15:数组的定义与使用
10、数组的基本概念
基本概念
数组用来表示一组类型相同的有序数据的集合,这些数据使用同一个标识符命名(数组名),数组中的每个数据叫数组元素,可通过下标来访问,下标从0开始。
和变量一样,数组必须先定义,后使用。定义数组时确定数组的名称、数据类型,还要为它分配内存、初始化。
- 数组是引用数据类型,而使用引用数据类型时必须先分配内存。
数组动态初始化
在Java中,数组也是一种对象。类中定义的方法都可以用于数组对象。
数组的动态初始化:
- 声明并开辟数组(实例化):
数组类型 数组名称 [] = new 数据类型 [长度] ;
- 分布进行数组空间开辟(实例化):
- 声明数组:
数组类型 数组名称 [] = null ;
- 开辟数组空间:
数组名称 = new 数据类型 [长度] ;
- 声明数组:
[]
可以在数组名称前,也可以在数组名称后。
当数组开辟空间之后可以采用如下的方式进行操作:
- 数组的访问通过索引完成,即
数组名称[索引]
,注意索引从0开始,到长度-1为止;- 超出索引范围会有
ArrayIndexOutOfBoundsException
异常;
- 超出索引范围会有
- 当数组采用动态初始化开辟空间之后,数组里的每一个元素都是该数组对应数据类型的默认值
- 数组元素的赋值:
数组名称 [索引号] = 数据 ;
- 数组本身是一个有序且有限的集合操作,所以对于数组的内容操作可以采用for循环的模式完成。
- 为了便于使用for循环,Java中有一种动态取得数组长度的方法:
数组名称.length
- 为了便于使用for循环,Java中有一种动态取得数组长度的方法:
范例:动态初始化定义一个int型数组
public class ArrayDemo {
public static void main(String args[]) {
// 数组类型 数组名称 [] = new 数据类型 [长度] ;
int data [] = new int [4] ; // 开辟了一个长度为4的数组、
data [0] = 1 ;
data [1] = 1 ;
data [3] = 2 ;
data [2] = 3 ;
System.out.println(data.length) ;
for(int x = 0 ; x < data.length ; x++){
System.out.println(data[x]) ;
}
}
}
除了声明并开辟空间之外还有一种分步的开辟模式:
- 范例:观察分布开辟模式
public class ArrayDemo {
public static void main(String args[]) {
// 声明数组:数组类型 数组名称 [] = null ;
int data [] = null ;
// 开辟数组空间:`数组名称 = new 数据类型 [长度] ;
data = new int [4] ;
data [0] = 1 ;
data [1] = 1 ;
data [3] = 2 ;
data [2] = 3 ;
System.out.println(data.length) ;
for(int x = 0 ; x < data.length ; x++){
System.out.println(data[x]) ;
}
}
}
总结
数组属于引用数据类型,在使用之前一定要先在内存开辟空间(实例化),如果使用了没有开辟空间的数组,会出现NulllPointerException
异常信息。
public class ArrayDemo {
public static void main(String args[]) {
// 声明数组:数组类型 数组名称 [] = null ;
int data [] = null ;
// 没有开辟空间操作
System.out.println(data.length) ;
}
}
这一原则与之前讲解的对象操作是完全相同的。
11、数组的引用传递
首先研究数组的空间开辟:
范例:观察一道程序
public class ArrayDemo {
public static void main(String args[]) {
// 声明数组:数组类型 数组名称 [] = null ;
int data [] = null ;
// 开辟数组空间:`数组名称 = new 数据类型 [长度] ;
data = new int [4] ;
data [0] = 1 ;
data [1] = 1 ;
data [3] = 2 ;
data [2] = 3 ;
for(int x = 0 ; x < data.length ; x++){
System.out.println(data[x]) ;
}
}
}
观察内存分析:
可以发现,数组的内存开辟与对象几乎是相同的。
因此,数组的引用传递可以与同为引用数据的对象进行类比:
- 同一块堆内存(存放数组的内容)可以被不同的栈内存所指向。
范例:观察一道程序
public class ArrayDemo {
public static void main(String args[]) {
int data [] = new int [4] ;
int temp [] = null ; // 声明一个数组(没有开辟空间)
data [0] = 1 ;
data [1] = 1 ;
data [3] = 2 ;
data [2] = 3 ;
// 如果要发生引用传递,不要出现[]
temp = data ;
temp[0] = 99 ;
for(int x = 0 ; x < data.length ; x++){
System.out.println(data[x]) ;
}
}
}
观察内存分析:
12、数组的静态初始化
- 动态初始化有一个明显特点:数组先开辟内存空间,而后再使用索引进行内容的设置。
- 而如果希望数组在定义的时候可以同时设置内容,可以使用静态初始化。
语法有以下两种:
- 简化格式:
数据类型 数组名称 [] = {值,值,······} ;
- 完整格式:
数据类型 数组名称 [] = new 数据类型 [] {值,值,······} ;
推荐使用完整格式,因为这样可以使用匿名数组的概念。
- 范例:静态初始化定义一个数组
public class ArrayDemo {
public static void main(String args[]) {
int data [] = new int [] {1,1,2,3,5,8,13,21} ;
for(int x = 0 ; x < data.length ; x++){
System.out.println(data[x]) ;
}
}
}
范例:匿名数组
public class ArrayDemo {
public static void main(String args[]) {
System.out.println(new int [] {1,1,2,3,5,8,13,21}.length) ;
}
}
13、二维数组(了解)
概念
- 只需要一个索引就可以访问的数组类似一个数据行的概念:
索引 | 0 | 1 | 2 | ··· | 长度-1 |
---|---|---|---|---|---|
内容 | x | y | z | ··· | xx |
通过一个索引可以取得唯一的一个记录,这样的数组可以认为是一维数组。 |
- 而二维数组本质上是一个行列的组合,即想要取得某个数据需要行索引和列索引来进行定位:
数组名称[行索引][列索引]
索引 | 0 | 1 | 2 | ··· | 长度-1 |
---|---|---|---|---|---|
0 | x | y | z | ··· | xx |
1 | a | b | c | ··· | ac |
··· | l | m | n | ··· | nm |
长度-1 | r | s | t | ··· | rt |
比如,要访问数据c,通过:数组名[1][2] 。 |
初始化
- 动态初始化
数组类型 数组名称 [] [] = new 数据类型 [行长度] [列长度] ;
- 静态初始化
数据类型 数组名称 [] [] = new 数据类型 [] [] { {值,值,······} , {值,值,······} };
范例:定义一个二维数组
非重点,不细学了。
14、数组与方法调用(重点)
数组是引用数据类型,而所有的引用数据类型都可以为其设置多个栈内存指向。所以在进行数组操作时也可以通过方法对其进行处理
范例:使用方法接收数组
public class ArrayDemo {
public static void main(String args[]) {
int data [] = new int [] {1,1,2,3,5,8,13,21} ;
printArray(data) ; // int temp [] = data ;
}
// 定义一个专门进行数组输出的方法
public static void printArray(int temp[]) {
for(int x = 0 ; x < temp.length ; x++){
System.out.print(temp[x] + "、") ;
}
}
}
内存分析的原理还是这张图:
范例:方法返回数组
public class ArrayDemo {
public static void main(String args[]) {
int data [] = recv() ; //接收数组
printArray(data) ; // int temp [] = data ;
}
// 此时的方法希望可以返回一个数组类型,所以返回值类型定义为数组data对应的整型数组
public static int[] recv() {
return new int [] {1,1,2,3,5,8,13,21} ; // 匿名类
}
// 定义一个专门进行数组输出的方法
public static void printArray(int temp[]) {
for(int x = 0 ; x < temp.length ; x++){
System.out.print(temp[x] + "、") ;
}
}
}
既然此时发生了引用传递,也就意味着方法接受数组之后也可以对数组进行修改。
范例:定义一个方法,该方法可以改变数组内容
public class ArrayDemo {
public static void main(String args[]) {
int data [] = recv() ; //接收数组
change(data) ; // 改变数组内容
printArray(data) ; // int temp [] = data ;
}
// 此时的方法希望可以返回一个数组类型,所以返回值类型定义为整型数组
public static int[] recv() {
return new int [] {1,1,2,3,5,8,13,21} ; // 匿名类
}
//
public static void change(int arr[]) { // 没有返回值
for(int x = 0 ; x < arr.length ; x++){
arr[x] *= 2 ;
}
}
// 定义一个专门进行数组输出的方法
public static void printArray(int temp[]) {
for(int x = 0 ; x < temp.length ; x++){
System.out.print(temp[x] + "、") ;
}
}
}
15、Java对数组的支持
在Java本身给出的类库中也提供有对于数组操作的相关的支持方法:
数组排序
对数组内容进行升序排序。
方法:java.util.Arrays.sort(数组名称) ;
范例:实现数组排序操作
public class ArrayDemo {
public static void main(String args[]) {
int data [] = new int [] {312,564,2,489,13} ;
char c [] = new char [] {'终','不','似','少','年','游'} ;
java.util.Arrays.sort(data) ;
java.util.Arrays.sort(c) ;
printArray(data) ;
printArray(c) ;
}
// 定义一个专门进行数组输出的方法
public static void printArray(int temp[]) {
for(int x = 0 ; x < temp.length ; x++){
System.out.print(temp[x] + "、") ;
}
System.out.println() ;
}
// 类的重载
public static void printArray(char temp[]) {
for(int x = 0 ; x < temp.length ; x++){
System.out.print(temp[x] + "、") ;
}
System.out.println() ;
}
}
只要是基本数据类似的数组,java.util.Arrays.sort(数组名称) ;
都可以进行排序处理。
数组拷贝
用一个数组的部分内容替换掉另一个数组的部分内容(等长)。
方法:System.arraycopy(原数组名称,原数组开始点,目标数组名称,目标数组开始点,拷贝长度) ;
范例:观察一个数组拷贝操作
public class ArrayDemo {
public static void main(String args[]) {
int data [] = new int [] {1,2,3,4,5} ;
int num [] = new int [] {6,7,8,9,0} ;
// data中的1,2,3被替换为num中的7,8,9
System.arraycopy(num,1,data,0,3) ;
printArray(data) ;
}
// 定义一个专门进行数组输出的方法
public static void printArray(int temp[]) {
for(int x = 0 ; x < temp.length ; x++){
System.out.print(temp[x] + "、") ;
}
System.out.println() ;
}
}