首页 > 技术文章 > 六、JavaSE语言基础之数组

byuan 2021-06-29 14:47 原文

一维数组(关键字[])

关于数组的一些概念:

数组是多个基本数据有机组合形成一个复杂数据,是一个引用数据类型数据。

数组:装指定数量元素类型相同的数据的容器。

元素:在数组中,数组中的每个数据称之为数组的元素。

数组的定义

创建数组前必须先明确两点:元素类型元素个数

创建数组对象共有三种格式

格式1:元素类型[] 数组名 = new 元素类型[元素个数];

格式2:元素类型[] 数组名 = new 元素类型[]{值1,值2,值3...};

格式3:元素类型[] 数组名 = {值1,值2,值3...};

格式3是格式2的简写,编译器会自动补齐

一条创建数组对象语句做了哪些事?

int[] arr = new int[10];
//左边 -> int []arr:定义一个要指向int数组的数组名arr;
//右边 -> new int[10]:创建一个装10个int元素的数组对象;
//中间 -> 让左边的数组名arr指向右边的数组对象;  

关于数组应该注意的几点:

1、数组名存放的是所创建数组对象的地址;

2、关键字new每被调用一次就会创建一个新的对象(新的数组);

3、使用print语句打印引用数据类型的名字,所得结果是对象类型@对象的16进制内存地址;(字符数组除外,打印字符数组,打印的是元素组成的字符串)如:[I@7852e922;[:数组关键字、I:数据类型int、@之后:地址

4、数组中的元素如果没有赋值,编译器会赋予一个默认初始值,默认初始值是什么,取决于元素的类型。

5、获取数组元素的所有个数:对象名.length

使用数组好处:

1、数组会给其中的元素自动分配编号(索引、下标)编号0开始。

2、可以通过数组名加编号的方式为其赋值和获取该元素中存放的数据的值。

格式:数组名[元素下标];

数组元素的赋值格式:

数组名[数组下标]=符合该数组数据类型的数据;

在学习完数组之后,我们可能会遇到的第一个异常(编译器不会自动报错):

ArrayIndexOutOfBoundsException//数组下标越界异常

数组的遍历及求最大值

数组的遍历主要有两种方式:

方式1:使用for循环;

方式2:使用foreach语句;

求数组的最大值的思路如下:

1、假定数组第一位元素为最大值(max=array[0])

2、从数组的第二位元素开始向后遍历,依次与假定最大值max进行比较;如果大于max,则将max重新赋值;

数组的排序

在学习数组的排序之前,我们先学习如何交换两个变量的值,通常使用的方法有两种:

1、引入第三变量;

int a=3;
int b=8;

int c=a;//a=3 b=8 c=3
a=b;//a=8 b=8 c=3
b=c;//a=8 b=3 c=3 

2、求和法;

int a=3;
int b=8;
a=a+b;//a=11 b=8
b=a-b;//a=11 b=3
a=a-b;//a=8 b=3

顺序排序

思想:依次拿当前元素和其后面的所有元素做比较。

int[] array = {1, 3, 5, 7, 9, 0, 8, 6, 4, 2};
int temporary;
for (int i = 0; i < array.length - 1; i++) { 
    for (int j = i+1; j < array.length; j++) {
        if (array[i] > array[j]) {
            temporary = array[i];
            array[i] = array[j];
            array[j] = temporary;
        }
    }
}

/*
关于顺序排序双层for循环的取值范围的两个问题:

1、为什么外层for循环的取值范围是i<array.length-1;
因为顺序排序的比较轮数是array.length-1;外层for初始值为0,所以外层for循环的取值范围是i<array.length-1;

2、为什么内层for循环的取值范围是j<array.length;
顺序排序的规则是依次拿当前元素和其后面的所有元素做比较;数组中的最后一个元素下标是array.length-1,j取值j<array.length;刚好在这个范围之中;
*/

冒泡排序

思想:依次拿相邻元素做比较

int[] array = {1, 3, 5, 7, 9, 0, 8, 6, 4, 2};
int temporary;
for(int round=0;round<array.length;round++){
    for(int index=0;index<array.length-i-1;index++){
        if(array[index]<array[index+1]){
            temporary=array[index];
            array[index]=array[index+1];
            array[index+1]=temporary;
        }
    }
}  

/*
关于冒泡排序双层for循环的取值范围的两个小问题:

1、为什么外层for循环的取值范围是i<array.length-1;
因为顺序排序的比较轮数是array.length-1;for初始值为0,所以外层for循环的取值范围是array.length-1;

2、为什么内层for循环的取值范围是j<array.length-i-1;
冒泡排序的规则是依次拿相邻元素做比较,最值会逐渐向后移动,直至数组末尾;也就是说经n轮排序后,数组末尾是一个有序元素组合,故末尾无需继续进行比较,也就是说每次的比较次数是递减的,故-i,以使内层循环次数递减;
*/

关于顺序排序与冒泡排序的小结:

顺序排序与冒泡排序的语法结构极为相似,但需要注意一点,顺序排序与冒泡排序的外层for循环虽然取值范围一样,但代表的含义却完全不同。顺序排序的外层for循坏不仅代表了需要进行比较的轮数,同时也代表了需要与后续元素进行比较的元素的下标,而冒泡排序的外层for循环则仅代表比较的总轮数;

插入排序排序

**思想: **

将整个数组array分为有序和无序的两个部分,前者在左边,后者在右边;

开始有序的部分只有array[0] , 其余都属于无序的部分,每次取出无序部分的第一个(最左边)元素,把它加入有序部分。

假设插入合适的位置p,则原p位置及其后面的有序部分元素都向右移动一个位置,有序的部分即增加了一个元素。

一直做下去,直到无序的部分没有元素;

int[] array = {3, 1, 4, 6, 5, 9, 8, 7};
for(int indexLow = 1; indexLow < array.length; indexLow++) {
    int interem = array[indexLow];
    int indexHigh = indexLow - 1;
    for(;indexHigh >=0; indexHigh --) {
        if(array[indexHigh]>interem) {
            array[indexHigh +1]=array[indexHigh];
        }else {
            break;
        }
    }
    array[indexHigh +1]=interem;
} 

二维数组

n维数组:装指定数量相同类型的n-1维数组的容器,n维数组的元素是n-1维数组

二维数组关键字:[] []

创建二维数组的三种格式:

格式1:元素类型[][] 数组名 = new 元素类型[一维数组的个数][一维数组中元素的个数];

格式2:元素类型[][] 数组名 = new 元素类型[][]{{值1,值2..},{值1,值2..},{值1,值2..}};

格式3:元素类型[][] 数组名 = {{值1,值2..},{值1,值2..},{值1,值2..}};

int [][]arr = new int[3][4];
//arr:二维数组的名字、new int[3][4]:二维数组对象
//3:二维数组中有3个一维数组、4:每个一维数组中有4个元素
System.out.println(arr);//[[I@7852e922,二维数组地址
System.out.println(arr.length);//arr.length:二维数组中一维数组的个数
System.out.println(arr[0]);//[I@4e25154farr[i]:二维数组中下标为i的一维数组对象
System.out.println(arr[0].length);//arr[i].length:二维数组中下标为i的一维数组中的元素个数
System.out.println(arr[0][1]);//arr[i][j]:二维数组中下标为i的一维数组中下标为j的元素

遍历二维数组的方式:使用双层循环;

推荐阅读