数组的基础运用
数组是同一种数据类型的集合,是一个长度固定的持有数据类型。数组也是引用类型(包括类,接口和数组)中的一种,数组内的每一个数据称为一个元素,值为数组的变量叫做引用。
数组能够将数据进行分组,进行分类后整理有利于数据的操作。
1. 一维数组
数组的使用必须要进行声明和初始化。
1. 一维数组的声明
数组内只能同时存放一种数据类型的数组;
Ø 可以是基本数据类型(byte,short, int, long, float, double, char, boolean)
Ø 也可以是引用数据类型 (String等)
数组是一个对象,成员是数组内的成员元素和数组的长度等数组的属性;
声明数组变量,并不是创建了一个数组对象,而是创建了一个指针一样的数据引用。使用new创建数组实例,才会开始分配内存空间,才是创建了一个数组对象。数组对象本身存储在堆中,而数组的引用(堆中的内存地址)则存储在栈中。
数组内存分配过程
声明数组的形式:
- int []array:基本数据类型数组,数组内存放的是基本的数据类型
- String []array 类类型数组,数组内存放的是String类类型的对象
注意:数组声明的时候,不能够设置长度。所以int arr[1]; 和 int[2] arr;都是非法的。
之所以这样设置初始化声明是因为前面声明的变量并不是数组实例,而是实例的一个引用地址。关于数组的长度及其元素的个数是由后方的数组实例决定的.
2. 一维数组的初始化
一维数组的初始化方式有三种:
方式一:
元素类型[] 数组名 = new 元素类型[元素个数(即数组的长度)];
e.g. int[] arr = new int[5];
这种方式下,会为数组内的每个元素赋予其数据类型的默认值:
- 整数类型byte/short/int/long–> 0
- 浮点数类型float –>0.0f
- 浮点数类型double –>0.0d
- 字符串类型String –>null
- char类型–> ‘\u0000’(unicode编码)
- boolean布尔类型–> false
arr: (0x123):值如下
0 | 0 | 0 | 0 | 0 |
方式二:
元素类型[] 数组名 = new 元素类型[]{元素,元素,元素,……};
e.g. int[] arr = new int[]{1,2,3,4,5};
方式三:(是对方式二的简化)
元素类型[] 数组名 = {元素,元素,元素,……};
e.g. int[] arr = {1,2,3,4,5};
对于数组中的三个“空”的理解:
1) String[]a; //未初始化, 仅仅声明了变量,未创建实例,未分配内存
2) String[] a = “”;or String[] a = new String[]{“”}; //创建了实例,并分配了内存,其值 为“”;
3) String[] a = null; //已初始化,当未指向任何对象,故引用时会报空指针异常
3. 一维数组的常用方法
1. 遍历
public static void printArray(int[]a){
for(int i=0;i<a.length;i++){
print(a[i]+””);
}
}
2. 判断数组是否有指定的值
public static boolean findElement(int[]a,int element){
for(int i=0;i<a.length;i++){
if(a[i]== element){
return true;
}
}
return false;
}
3. 数组翻转
public static int[] reversal(int[] a){
int length = a.length;
if(length%2==0){
for(int i=0;i<length/2;i++){
int k=a[i];
a[i]= a[length-1-i];
a[length-1-i]=k;
}
}else{
for(int i=0;i<(length-1)/2;i++){
int k=a[i];
a[i]= a[length-1-i];
a[length-1-i]=k;
}
}
return a;
}
//或者
public static int[] reversal(int[] a){
int length = a.length;
int[]temp = new int[length];
for(int i=0;i<length;i++){
temp[i]= a[length-1-i];
}
return temp;
}
4. 求最值
//求最大值
public static int max(int[]a){
int max = a[0];
for(int i=0;i<a.length;i++){
max= max>a[i]?max:a[i];
}
return max;
}
//求最小值
public static int min(int[]a){
int min= a[0];
for(int i=0;i<a.length;i++){
min= min<a[i]?min:a[i];
}
return min;
}
5. 排序
见上一篇博客,分直接选择排序和冒泡排序
4. 数组的常见错误
- 数组脚标越界异常(ArrayIndexOutOfBoundsException)
原因:访问了不存在的索引
- 空指针异常(NullPointerException)
原因:访问的引用没有指向堆栈内存中的实例对象。
- 数组传参与基本数据类型传参辨析
当基本数据类型作为参数传入函数时,在函数内修改该值不会对函数外的变量值产生影响
当引用数据类型作为参数传入函数时,在函数内修改该引用指向的对象值时便更改了堆内存对象,会影响函数外的引用。
2. 二位数组
二位数组是以数组作为元素的数组,即数组中包含数组。
二维数组的使用也需要进行声明和初始化,方式与一维数组相似。
1. 二维数组的初始化
方式一:
元素类型[][] 数组名 = new 元素类型[内层数组长度][外层数组长度];
e.g. int[][] arr = new int[3][4]; //这种方式初始化的数组第一维(内层)的数组长度相同
方式二:
元素类型[][] 数组名 = new 元素类型[内层数组长度][];
e.g. int[] arr = new int[3][]; // 每一个一维数组的默认值为null,需要使用其他数组赋值, 且无法使用第三种方式赋值
方式三:
元素类型[][] 数组名 = {{元素,元素,元素,元素},{元素,元素,元素},{元素,元素}…. };
e.g. int[] arr = {{1,2,3,4},{5,6,7},{8,9,10,11,12}};// 指定数组内数组的具体元素值
2. 二维数组的常用方法
1. 遍历
public static void printAarry(int[][] arr){
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
System.out.print(arr[i][j]+"");
}
System.out.println();
}
}
2. 求和
public static int sum(int[][] arr){
int sum = 0;
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
sum+= arr[i][j];
}
}
return sum;
}
3 求最值
//求最大值
public static int max(int[][] arr){
int max = arr[0][0];
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
max =max>arr[i][j]?max:arr[i][j];
}
}
return max;
}
//求最小值
public static int min(int[][] arr){
int min = arr[0][0];
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
min = min<arr[i][j]?min:arr[i][j];
}
}
return min;
}
4 杨辉三角
public static void printYHTrangle(int length){
int arr[][] = new int[length][];
for(int i = 0; i < arr.length; i++) {
arr[i]= new int[i + 1];
}
for(inti=0;i<=length-1;i++){
arr[i][0]= 1;
arr[i][i]= 1;
if(i>=2){
for(intj=1; j<i;j++){
arr[i][j]= arr[i-1][j-1]+arr[i-1][j];
}
}
}
printAarry(arr); //遍历方法如上
}