一、什么是数组

  • 数组是存储同一种数据类型多个元素的集合。也可以看成是一个容器。
  • 数组既可以存储基本数据类型,也可以存储引用数据类型。
  • 数组一旦初始化,长度不可变

二、一维数组

  • 一维数组的声明方式:类型 数组名[] 或 类型[] 数组名,例如:
int a[];
int[] a1;
double b[];
Date[] c;		//对象数组
  • 单独声明数组时不能指定其长度(数组中元素的数),例如:
int a[5];    //非法
  • 这两种定义做完了,数组中是没有元素值的

1、数组的初始化

  • Java中的数组必须先初始化,然后才能使用
  • 所谓初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋值
  • Java中可以使用关键字new创建数组对象,完成静态初始化或动态初始化

1.1、动态初始化

  • 动态初始化:初始化时只指定数组长度,由系统为数组分配初始值
  • 格式:数据类型[] 数组名 = new 数据类型[数组长度],如 int[] arr = new int[3];
  • 数组长度其实就是数组中元素的个数
1.1.1、数组中的元素
  • 定义并用运算符new为之分配空间后,才可以引用数组中的某个元素;
  • 每个数组都有一个属性length 指明它的长度,例如:a.length指明数组a 的长度(元素个数);
  • 数组名和编号的配合就可以获取数组中的指定编号的元素。即索引(下标);
  • 数组元素的引用方式:数组名[数组元素下标]
  • 数组元素下标可以是整型常量或整型表达式。如a[3] , b[i] , c[6*i]
  • 数组元素下标从0开始;长度为n的数组合法下标取值范围: 0 至n-1
1.1.2、内存结构
  • 动态初始化数组时,由系统给出初始值,初始值为0
  • Java中内存的申请和释放都是 JVM进行管理的,Java程序要运行,JVM都会自动的向电脑申请一块内存,把这块内存分为五部分:
  1. 栈(Stack):主要存放局部变量,即在方法定义中或方法声明上的变量
  2. 堆(Heap):凡是new出来的都存在堆里面,堆当中的数据都有默认原则
    整数:0,小数:0.0,布尔:false,char:空格,引用数据类型:null
  3. 方法区(Method Area):存放的是与.class相关的信息
  4. 本地方法区(Native Method Area):与操作系统有关
  5. 寄存器(Register):与CPU有关

堆内存的特点

  • 每一个new出来的东西都会有一个地址;
  • 每个变量都会有默认值;
  • 使用完毕就变成了垃圾,但是并没有立即回收,会等到垃圾回收器空闲时回收。

栈内存的特点

  • 用完就释放掉

1.2、静态初始化

  • 静态初始化:初始化时指定每个数组元素的初始值,由系统决定数组长度
  • 格式:数据类型[] 数组名= new 数据类型[]{元素1,元素2,…}
  • 举例:int[] arr = new int[]{1,2,3} 或 int[] arr= {1,2,3}

注意:
int[] a = new int[]

  • new的时候就要分配内存,不指定就不知道分配多少;
  • 数组一旦初始化,长度不可变。

1.3、数组常见问题

1.3.1、数组索引越界
  • ArrayIndexOutOfBoundsException
  • 访问到了数组中的不存在的索引时发生
1.3.2、空指针异常
  • NullPointerException
  • 数组引用没有指向实体,却在操作实体中的元素时

2、数组排序

2.1、冒泡排序

冒泡排序的基本思路:
假设要被排序的数组arr[0…n-1]是垂直放置的,我们将其中的每个元素都看成重量为arr[i]的气泡。那么,根据常识,我们知道重量轻的气泡会向上冒。所以我们制定轻气泡不能在重气泡下的原则。现在,我们从下向上扫描数组arr[n]中的每个元素,凡是发现违反本原则的轻气泡,就使其向上“冒”,反复的执行这个过程,直到所有元素都满足该原则。

2.1.1、冒泡算法原理
  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  • 针对所有的元素重复以上的步骤,除了最后一个。
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
2.1.2、冒泡排序效果

分析:每次比较相邻两数小的交换到前面每轮结束后最大的数交换到最后

java有可变数组吗_数组

2.1.3、代码框架:
for (i = 0; i < N-1 ; i++){       //外层控制趟数
	for (j = 0; j < N-1-i; j++){  //内层控制次数
		// 比较j 和j+1 位置的元素
		// 如果前大后小就交换
	}
}
/**
*冒泡排序速记口诀(升序):
* N 个数字来排队
* 两两相比小靠前
* 外层循环N-1
* 内层循环N-1-i
*/
2.1.4、冒泡排序示例:
/*
*使用冒泡算法对数组排序
*int[] number  =new int[]{20,5,17,28,19,15,29,87,65,32}
*要求:从大到小进行打印
**/

public void test5() {
        int temp;
        int[] number = new int[]{20,5,17,28,19,15,29,87,65,32};
        for (int i = 0; i < number.length - 1; i++) {
            for (int j = 0; j < number.length - 1 - i; j++) {
                if (number[j] < number[j + 1]) {
                    temp = number[j];
                    number[j] = number[j + 1];
                    number[j + 1] = temp;
                }
            }
        }
        /*for (int n : number) {
            System.out.print(" "+n);
        }*/
        System.out.println(Arrays.toString(number));
    }

2.2、选择排序(了解)

算法描述:
对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录的位置进行交换;接着对不包括第一个记录以外的其他记录进行第二轮比较,得到最小的记录并与第二个记录进行位置交换;重复该过程,直到进行比较的记录只有一个时为止。

三、多维数组

二维数组[][]:数组中的数组

格式1(动态初始化):int[][] arr= new int[3][2];

  • 定义了名称为arr的二维数组
  • 二维数组中有3个一维数组
  • 每一个一维数组中有2个元素
  • 一维数组的名称分别为arr[0], arr[1], arr[2]
  • 给第一个一维数组1脚标位赋值为78写法是:arr[0][1] = 78;

格式2(动态初始化):int[][] arr= new int[3][];

  • 二维数组中有3个一维数组
  • 每个一维数组都是默认初始化值null (注意:区别于格式1)
  • 可以对这三个一维数组分别进行初始化
    arr[0] = new int[3]; arr[1] = new int[1]; arr[2] = new int[2];
  • 注:int[][] arr= new int[][3]; //非法,第一个值不能为空

格式3(静态初始化):int[][] arr= new int[][]{{3,8,2},{2,7},{9,0,1,6}};

  • 定义一个名称为arr的二维数组,二维数组中有三个一维数组
  • 每一个一维数组中具体元素也都已初始化
  • 第一个一维数组arr[0] = {3,8,2};
  • 第二个一维数组arr[1] = {2,7};
  • 第三个一维数组arr[2] = {9,0,1,6};
  • 第三个一维数组的长度表示方式:arr[2].length;

➢注意特殊写法情况:int[] x,y[]; x是一维数组,y是二维数组。
➢Java中多维数组不必都是规则矩阵形式

二维数组示例:

public void test6() {
        int[][] house = new int[][]{{101,102,103,104},{201,202,203,204},{301,302,303,304}};
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                System.out.print(house[i][j]+" ");
            }
            System.out.println();
        }
    }