数组

Posted on 2019-12-13 19:43  马鸣浩  阅读(114)  评论(0编辑  收藏  举报

数组的概念

数组:用来存储和管理一组相同数据类型的数据。它是一种容器。

数组名:为了方便存储和管理一组相同数据类型的数据,使用一个统一的名称来管理它们。

下标:为了区别一组数组中的每一个,使用编号/索引/下标来表示

元素:这一组数据中的每一个数据是一个元素,表示方式:数组名[下标]

数组的长度:数组的元素的总个数,表示方式:数组名.length

下标的范围:[0, 数组的长度-1]

数组名:记录这一组数据在“堆”内存中的首地址。

下标从0开始:距离首地址间隔0个单元格

一维数组

1、声明的格式

元素的数据类型[] 数组名;//推荐

或

元素的数据类型  数组名[];

2、初始化方式

(1)静态初始化

元素的数据类型[] 数组名 = {元素值1,元素值2。。。。};

//如果分开两行
元素的数据类型[] 数组名;
数组名 = new 元素的数据类型[]{元素值1,元素值2。。。。};

静态初始化的方式,在创建数组对象的同时就指定了数组的元素的值,而且数组的长度由列出来的元素的个数决定。

(2)动态初始化

元素的数据类型[] 数组名 = new 元素的数据类型[长度];

//如果分开两行
元素的数据类型[] 数组名;
数组名 = new 元素的数据类型[长度];

动态初始化的方式,在我们创建完数组对象时,还没有为元素赋值的话,元素是默认值。

3、为元素赋值

数组名[下标] = 值;

arr[i] = 常量值; //常量值为元素赋值
arr[i] = (int)(Math.random()*100); //使用随机数为元素赋值
arr[i] = input.nextInt(); //从键盘输入为元素赋值
arr[i] = i*2 + 1; //使用表达式的结果为元素赋值

4、遍历

for(int i=0; i<数组的长度; i++){
	//数组名[i]表示元素
}

5、数组元素的默认值

byte,short,int,long:默认值是0

float,double:默认值是0.0

char:默认值是编码值为0的字符,\u0000

boolean:默认值是false

引用数据类型:null

6、一维数组的内存分析

凡是数组,即new出来都在堆中。

数组的元素是连续存储的。

一维数组的基础算法

求和

int[] arr = {3,2,5,1,4};

int sum = 0;
for(int i=0; i<arr.length; i++){
	sum += arr[i];
}

求均值

int[] arr = {3,2,5,1,4};

double sum = 0;
for(int i=0; i<arr.length; i++){
	sum += arr[i];
}

double avg = sum / arr.length;

统计偶数/奇数个数

int[] arr = {3,2,5,1,4};

int odd = 0;
int even = 0;
for(int i=0; i<arr.length; i++){
	if(arr[i] % 2==0 ){
		even++;
	}else{
		odd++;
	}
}

查找

顺序查找

int[] arr = {3,2,5,1,4};

int findValue = ?;

int index = -1;
for(int i=0; i<arr.length; i++){
    if(arr[i] == findValue){
        index = i;
        break;
    }
}
if(index==-1){
    System.out.println("不存在");
}else{
    System.out.println(findValue + "的下标是" + index);
}
String[] names = {"张三","李四","王五"};

String findValue = ?;

int index = -1;
for(int i=0; i<arr.length; i++){
    if(arr[i].equals(findValue)){
        index = i;
        break;
    }
}
if(index==-1){
    System.out.println("不存在");
}else{
    System.out.println(findValue + "的下标是" + index);
}

找最值

int[] arr = {3,2,5,1,4};

int max = arr[0];//假设第一个最大
//和后面的元素一一比较
for(int i=1; i<arr.length; i++){
	if(arr[i] > max){
		max = arr[i];
	}
}

找最值下标

int[] arr = {3,2,5,1,4};

int max = arr[0];//假设第一个最大
int index = 0;
//和后面的元素一一比较
for(int i=1; i<arr.length; i++){
	if(arr[i] > max){
		max = arr[i];
        index = i;
	}
}
int[] arr = {3,2,5,1,4};

int index = 0;//假设第一个最大
//和后面的元素一一比较
for(int i=1; i<arr.length; i++){
	if(arr[i] > arr[index]){
        index = i;
	}
}

System.out.println("最大值是:" + arr[index]);

排序

冒泡排序:

结果:从小到大排序

(1)从左边开始把大的往右边移动

int[] arr = {3,2,5,1,4};

for(int i=1; i<arr.length; i++){
    /*
    因为每一轮从最左边开始,int j=0;起始值
    i=1, j=0,1,2,3
    i=2, j=0,1,2
    i=3, j=0,1
    i=4, j=0
    j<arr.length-i
    */
    for(int j=0; j<arr.length-i ; j++){
        //前面的元素 > 后面的元素
        /*
        前后元素:arr[j]与[j+1]
        前后元素:arr[j-1]与arr[j]  因为我这里j=0开始,arr[j-1]当j=0的时候会越界
        */
        if(arr[j] > arr[j+1]){
            int temp = arr[j];
            arr[j] = arr[j+1];
            arr[j+1] = temp;
        }
    }
}

(2)从右边开始把小的往左边移动

int[] arr = {3,2,5,1,4};

for(int i=1; i<arr.length; i++){
	/*
	因为从右边开始把小的往左边移动,所以j的起始点  arr.length-1
	i=1, j=4,3,2,1
	i=2, j=4,3,2
	i=3, j=4,3
	i=4, j=4
	int j = arr.length-1; j>=i; j--
	*/
	for(int j=arr.length-1; j>=i; j--){
		//右边的元素 < 左边的元素 交换
		/*
        右边与左边元素:arr[j]与[j-1]
        右边与左边元素:arr[j+1]与arr[j] 因为j的起始点arr.length-1,[j+1]会导致越界
        */
        if(arr[j] < arr[j-1]){
        	int temp = arr[j];
        	arr[j] = arr[j-1];
        	arr[j-1] = temp;
        }
	}
}

二维数组

1、声明格式

数组的元素类型[][] 数组名;//推荐写法

或
数组的元素类型 数组名[][];

或
数组的元素类型[] 数组名[];
class Test04Review4{
	public static void main(String[] args){
		//标准声明二维数组的方式
		int[][] arr1 = new int[3][];

		//其他的方式
		int arr2[][] = new int[3][];

		int[] arr3[] = new int[3][];

		System.out.println(arr1);//[[I@15db9742
		System.out.println(arr2);//[[I@6d06d69c
		System.out.println(arr3);//[[I@7852e922

		//面试题
		int[] x, y[];
		//答案:x是一维数组,y是二维数组

        //x = new int[2][];//错误,因为x是一维数组
		//y = new int[3];//错误的,一维y是二维数组
	}
}

2、初始化

(1)静态初始化

数组的元素类型[][] 数组名 = {{第一行的元素} , {第二行的元素} 。。。};

//分开两行代码
数组的元素类型[][] 数组名;
数组名 = new 数组的元素类型[][]{{第一行的元素} , {第二行的元素} 。。。};

(2)动态初始化:每一行的列数可能不同

数组的元素类型[][] 数组名 = new 数组的元素类型[总行数][];

//单独指定每一行的列数
数组名[行下标] = new 元素的类型[列数];//每一行是一个一维数组

(3)动态初始化:每一行的列数相同

数组的元素类型[][] 数组名 = new 数组的元素类型[总行数][列数];

3、遍历

二维数组的长度,二维数组的总行数:数组名.length

二维数组的某一行:数组名[行下标]

二维数组的某一行的列数,某一行的长度:数组名[行下标].length

行下标的范围:[0, 数组名.length-1]

二维数组的某个元素:数组名[行下标][列下标]

列下标的范围:[0, 数组名[行下标].length-1 ]

for(int i=0; i<数组名.length; i++){
	for(int j=0; j<数组名[i].length; j++){
		//元素:数组名[i][j]
	}
}

在数组使用过程中经常遇到的两种异常

1、数组下标越界异常:ArrayIndexOutOfBoundsException

一维数组的下标范围:[0, 数组名.length-1]

二维数组的行下标范围:[0, 数组名.length-1]

二维数组的列下标范围:[0, 数组名[行下标].length -1]

2、空指针异常:NullPointerExeption

元素是引用数据类型:

例如:String[],Student[]...

这种数组的元素的默认值是null,在给元素赋值之前,使用数组的元素进行.操作就会报空指针异常

String[] names = new String[3];
System.out.println(names[0].charAt(0));//names[0]是null

使用二维数组时,如果没有为行指定列数,那么此时行是null

int[][] arr = new int[3][];

System.out.println(arr[0].length);//arr[0]是null
System.out.println(arr[0][0]);//arr[0]是null