Java笔记第三章 数组

第三章 数组

一、数组的概述

  1. 数组(Array), 是多个相同类型数据按一定顺序排列的集合, 并使用一个名字命名, 并通过编号的方式对这些数据进行统一管理。

  2. 数组的相关概念:

    • 数组名

    • 下标(或索引)

    • 元素

    • 数组的长度

  3. 数组是引用数据类型 ,其内部元素既可以是基本数据类型,也可以是引用数据类型。

  4. 创建数组后会在内存中开辟一整块连续的空间,且数组的长度一旦确定,不能再修改。

  5. 数组的分类:

    • 按照维数:一维、二维、三维……
    • 按照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组

二、一维数组的使用

  1. 一维数组的声明和初始化

    1. 声明:数组中元素数据类型+[ ]+数组名

    2. 初始化:

      • 静态初始化:数组的初始化和数组元素的赋值操作同时进行

        int[ ] ids; //声明

        ids = new int[ ]{1,2,3,4}; //静态初始化,大括号前面为数组初始化,大括号里面为赋值

        这里的new int[ ]可以省略,称为类型推断

      • 动态初始化:数组的初始化和数组元素的赋值操作分开进行

        String[ ] names = new String[5]; //声明和动态初始化,只规定了数组元素个数

  2. 通过索引的方式调用指定位置元素的值,索引是从0开始的,这个方法和python里一样

  3. 通过.length属性来获取数组的长度

  4. 数组的遍历:用for循环进行遍历

    for(int i=0; i<array.length; i++){

    //里面通过索引的方式调用相应元素

    }

  5. 数组元素采用动态初始化时会有默认初始化值

    • 数组元素是整型的:0
    • 数组元素是浮点型的:0.0
    • 数组元素是char型:0或’\u0000’ 注意不是’0’
    • 数组元素是boolean型:false
    • 数组元素是引用数据类型:null
  6. 数组的内存解析

    内存的简化结构:

    • 栈(stack)主要用来存放局部变量。
    • 堆(heap)主要用来存放new出来的结构(对象,数组)
    • 方法区:分为常量池和静态域,String放在常量池,static放在静态域

    放在方法中的变量都叫着局部变量,左边数组名就是个变量,他定义在方法里也是局部变量,右边的new出来的,需要放在堆里,栈空间的变量存的是堆空间中数组的16位地址值,这个地址值存储在堆空间中的数组的最开始。

    如果同一个变量名重新new了一个数组,则会新开辟一个地址,栈空间中的原变量会变成新的地址,原来的数组会变成垃圾,会在后期空闲时间被自动清除。

    当程序执行完以后,存放在栈中的变量会依次出栈,然后堆空间的数组就会变成垃圾,随后会被清除。


三、多维数组的使用

  1. 可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。

  2. 一维数组的声明和初始化

    • 声明,例如:

      int[][] arr;
      int[] arr[];
      int arr[][];
      
    • 静态初始化:

      int[]][] arr1 = new int[][]{{1,2,3},{4,5},{6,8,7,9}};
      int[]][] arr2 = {{1,2,3},{4,5},{6,8,7,9}}
      
    • 动态初始化:

      String[][] arr1 = new String[3][2];//表示三行两列
      String[][] arr2 = new String[3][];//列可以不写,行必须写
      arr2[0] = new String[2];//采用这种方式初始化,必须要在后续对外层数组的每一个元素赋值
      
  3. 通过索引的方式调用指定位置元素的值,索引是从0开始的,这个方法和python里一样,对于动态初始化的第二种方式,如果要调用指定元素还需要再对列进行赋值如:arr2[1] = new String[4];

  4. 获取数组的长度arr.length返回的是第一维的个数,如果要返回第二维的长度需要arr[1].legth

  5. 如何遍历二维数组:

    利用循环嵌套,最外层就是第一维,然后依次类推

    for (int i = 0;i < arr.length; i++){
        for (int j = 0;j < arr[i].length;j++){
        }
    }
    
  6. 数组元素的默认初始值

    二维数组中外层数组如arr[1]中存放的是内层数组的地址值,内层数组的默认值和一维数组相同。

    **注意:**如果采用动态初始化的第二种,外层数组的默认值为null,这个null与声明的类型无关

  7. 内存解析

    • 栈(stack):存放变量名,变量名的值是外层数组在堆空间的首地址值
    • 堆(heap):外层数组中的每一个元素存放的是内层数组在堆空间的首地址值,内层数组存 放的是具体元素值

四、数组中涉及到的常见算法

  1. **数组元素的赋值(杨辉三角、回形数等) **

杨辉三角:

  • 第一行有 1 个元素, 第 n 行有 n 个元素

  • 每一行的第一个元素和最后一个元素都是 1

  • 从第三行开始, 对于非第一个元素和最后一个元素的元素。即:

yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];

回形数:

给定一个值如4,则输入四行四列,且其中的元素按顺序转圈打印,如下:

1 2 3 4

12 13 14 5

11 16 15 6

10 9 8 7

  1. 求数值型数组中元素的最大值、最小值、平均数、总和等

  2. 数组的复制、反转、查找(线性查找、二分法查找)

  • 数组复制:

    将一个数组赋值给另一个数组,只是将地址值赋值给了另一个数组,所以他俩都指向堆空间的同一位置,改变任意一个数组里元素,两个数组的元素值都会改变。简单的可以理解为如果有new才会在堆空间新建一个数组的空间,否则就只有原来的数组。(因此这种方式不能称为是复制)

    如果需要复制,首先需要先new一个新数组,然后通过for循环的方式去对其赋值,所赋的值等于原先数组对应位置的值

  • 数组反转:

    public static void main(String[] args){
        String[] arr = new String[]{"AA","BB","CC","DD","EE","FF"};
        for (int i = 0;i < arr.length/2;i++){
            String temp = arr[i];
            arr[i] = arr[arr.length - 1 - i];
            arr[arr.length - 1 - i] = temp;
        }
    }
    
  • 查找

    二分查找:

    • 前提:所要查找的数组必须有序
    • 然后跟中间元素比较,大于中间元素在右半边找(将索引的最小值改为中间值对应的索引),小于中间元素在左半边找(将索引的最大值改为中间值对应的索引,然后同理直到相等的元素或者分到只剩一个元素仍然不相等。
  1. 数组元素的排序算法
  • 十大内部排序算法:

    • 选择排序:直接选择排序、堆排序
    • 交换排序:冒泡排序快速排序
    • 插入排序:直接插入排序、折半插入排序、Shell排序
    • 归并排序
    • 桶式排序
    • 基数排序 (最后两种比较少,前八种使用较多)
  • 冒泡排序法:
    从头开始依次两两进行比较,如果大数在前则交换顺序,直到把最大的数放在最后,然后再从头开始两两比较,直到把次大的数放在倒数第二个位置,重复这样的操作直到排序完成。

  • 快速排序法:

    • 思想:

      分别取两个变量一个叫low,一个叫high,low开始指向第一个元素,并将第一个元素赋给一个变量,high开始指向最后一个元素,然后l先用high所指的数与第一个数进行比较,如果比第一个数大high-1并继续比较,如果小于将high所指的值赋给low,然后low+1,开始用low所指的数进行比较,用low所指的数与第一个数进行比较,如果小于第一个数,low+1,然后继续比较,如果大于等于第一个数,将low所指的数赋给high所指的位置,然后high-1,开始用high所指的数进行比较。直到当low等于high时,low所指的位置就是第一个数在排序后的位置。

      找到第一个数的位置后,数组被分成了两半,然后对这两半再分别采用上面的方法,分别找到这两半第一个元素所在位置,然后再次根据位置对半分,直到所有的都分到不能分为止,则此时排序完成。

    • 方法:

      采用递归的思想,首先最开始先找出第一个元素在数组中的位置,此时数组被分成了两半,对于这两半就采用递归方法,在定义函数时,需要传入原数组(因为只定义了一个数组,因此需要都在原数组上进行操作)、first(数组的第一个索引)、last(数组的最后一个索引),然后就根据上述思想进行实现。


五、Arrays工具类的使用

  1. java.util.Arrays是数组的工具类,里面有很多数组的方法,例如常用的:

    1boolean equals(int[] a,int[] b)判断两个数组是否相等。
    2String toString(int[] a)输出数组信息。
    3void fill(int[] a,int val)将数组全部用指定值填充
    4void sort(int[] a)对数组进行排序。
    5int binarySearch(int[] a,int key)对排序后的数组进行二分法检索指定的值。

六、数组使用中的常见异常

  1. 数组角标越界的异常:ArrayIndexOutOfBoundsExcetion
  2. 空指针异常:NullPointerException
    • 数组没有赋值直接调用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值