数组

数组是一种数据形式,它把具有相同类型的若干变量按一定的顺序组织起来。数组中的每一个数据称为数组元素,数组中的元素以索引来表示其存放的位置,索引从0开始,步长是1。根据存放元素的类型,可分为一维数组和多维数组。

声明数组

数组是引用数据类型,可以赋值为null

数组的声明方式:

  • 方式1:类型[] 数组名;
  • 方式2:类型 数组名[];

数组的初始化

初始化数组的两种方式(静态初始化和动态初始化),数组一旦初始化完成其长度也就固定了,不能改变,除非重新初始化。

静态初始化

静态初始化:初始化时指定每个元素的初始值,系统自动分配其长度。

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

简化语法:数组名 = {元素1,元素2,元素3,...元素n};

数组存放于堆内存,使用变量指向堆内存地址。

动态初始化

动态初始化:初始化时指定数组的长度,系统自动为数组分配初始值。

格式:数组名 = new 数组类型[数组长度];

不同数据类型的初始值如下:

类型 初始值
byte、short、int 0
long 0L
float 0.0F
double 0.0D
boolean false
char 'u0000'(表示空)
引用数据类型 null

初始化数组时,不能静态初始化和动态初始化同时使用,也就是说不能同时指定数组的元素和数组的长度。

数组操作

得到数组的长度

数组提供了length 属性,用来返回数组的长度,返回int类型的结果。

格式:int len = 数组名.length;

注意:length 是数组的属性不是方法,若数组还没初始化就调用length 属性,会报错:java.lang.NullPointException异常。

访问数组元素

格式:数组元素类型 变量名 = 数组名[index];

这里的数组元素类型就是声明数组时的类型。索引必须在[0,数组名.length - 1]之间,否则会报错:java.lang.ArrayIndexOutOfBoundsException异常.

给数组元素赋值

格式:数组名[index] = 元素类型常量;

遍历数组元素

一般使用for循环变量数组元素。

打印数组

打印数组名字的时候会打印数组对应的hashCode值,而不是数组里的元素值。需要手动变量数组打印元素。

方法参数的值传递机制

方法被调用时,方法里的参数是以值传递的方式传递的。

所谓值传递,就是将实际参数的副本传入方法,而参数本身不受影响。

值传递之基本类型

若是基本数据类型,就直接传递实参的副本。

值传递之引用类型

若是引用数据类型,就传递实际参数的16进制地址值的副本。

注意:不能使用“==”来判断两个数组是否相等。因为“==”比较的是引用的内存地址。

二维数组

如果数组中的每个元素都是一维数组,此时我们称其为二维数组。

二维数组就是一个一维数组里的每一个元素也是一维数组。

动态初始化二维数组:

数据类型[][] arr = new 数据类型outerLength;

不允许高维没分配空间而先给低维分配空间,如:

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

常见的数组算法操作

冒泡排序

最简单的排序法,基本思路:对未排序的个元素从头到尾依次比较相邻的两个元素的大小关系,若大于则交换位置,经过第一轮比较后可得出最大值,然后使用同样的方法把剩余的元素逐个比较即可。

容易看出若有N个元素,那么一个需要进行N-1轮比较,第M轮要进行N-M次比较。

static void bubbleSort(int[] arr){
    for (int i = arr.length; i > 1; i--){
        for (int j = 1; j <= i - 1; j++){
            if (arr[j - 1] > arr[j]){
                swap(arr,j,j-1);
            }
        }
    }
}

选择排序

基本思路:每一轮从待排序的数据元素中选择出最小的一个元素,顺序放在已拍好序的数列的最前位置,直到全部待排序的数据元素拍完。

static void selectionSort(int[] arr) {
    int minEle;//表示最小的元素的索引
    for (int count = 1; count <= arr.length - 1; count++){
        minEle = count - 1;//每一轮第一个比较的元素的索引
        for (int i = count; i <= arr.length - 1; i++){
            if (arr[minEle] > arr[i]){
                minEle = i;
            }
        }
        swap(arr, minEle, count);
    }
}

线性查找

查找一维数组里面某一个元素的索引值

static int search(int[] arr,int key){
    for (int i = 0; i < arr.length; i++){
        if(key == arr[i]){
            return i;
        }
    }
    return  - 1;
}

二分搜索法

static int binarySearch(int[] arr, int key) {
    int low = 0;
    int high = arr.length - 1;
    while (low <= high) {
        int mid = (low + high) >>> 1;
        int midValue = arr[mid];
        if (midValue < key) {
            low = mid + 1;
        } else if (midValue > key) {
            high = mid - 1;
        } else {
            return mid;
        }
    }
    return -1;
}

JDK内置的操作数组的工具方法

java.lang.System类里有数组拷贝的方法:

public static native void arracopy(Object src, int srcPos, Object dest, int destPos, int length);

java.util.Arrays:类中已经写好比如排序和搜索等方法。

方法的可变参数

方法中可以接收的参数不再是固定的个数,而是随着具体需求传递的多少来决定。

定义格式:返回值类型 方法名(参数类型... 形式参数){}

可变参数的特点:只能出现在参数列表的最后,可变参数的本质其实就是数组。

调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数:

static void show(int ... arr){
    System.out.println(Arrays.toString(arr));
}

增强for循环—— for - each

当只关心数组元素,而不关心数组索引,就可以使用增强for循环遍历数组中的元素;

格式:


for(元素数据类型 变量名:数组或集合对象){
    //TODO
}

标签: 数组, array, 初始化, 静态初始化, 动态初始化, 初始值, 值传递, 选择排序, 冒泡排序, 线性查找, 二分搜索, 二分查找, 可变参数, foreach