1.数组的概述
  • 数组(Array),是多个相同类型数据一定顺序排列的集合,并使用一个名称命名,并通过编号的方式对这些数据进行统一管理。
  • 数组的常见概念
    1)数组名
    2)下标(或索引)
    3)元素
    4)数组的长度
  • 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
  • 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
  • 数组的长度一旦确定,就不能修改。
  • 我们可以通过下标(索引的方式)调用指定位置的元素,速度很快。
  • 数组的分类
    1)按照维度:一维数组、二维数组、三维数组、...
    2)按照元素的数据类型分:基本数据类型元素的数组、引用数据类型元素的数据(即对象数组)
2.一维数组的使用
/*
    一维数组的使用:
        1.一维数组的声明和初始化
        2.调用数组指定位置的元素
        3.获取数组的长度
        4.遍历数组
        5.数组元素的默认初始化值
        6.数组的内存解析
 */
public class ArrayTest {
    public static void main(String[] args) {
        //1.一维数组的声明和初始化
        //1.1 静态初始化:数组的初始化和数组元素的赋值操作同时进行
        int[] ids = new int[]{1001,1002,1003,1004};
        //1.2 动态初始化:数组的初始化和数组元素的赋值操作分开进行
        String[] names = new String[5];

        //2.调用数组指定位置的元素:通过数组的下标进行赋值
        //数组的下标从0开始,到数组的长度-1结束
        names[0] = "张三";
        names[1] = "李四";
        names[2] = "王五";
        names[3] = "赵六";
        names[4] = "孙七";

        //3.获取数组的长度:属性:length
        System.out.println(names.length);

        //4.遍历数组
        for(int i = 0;i < names.length;i++) {
            System.out.println(names[i]);
        }

        //5.数组元素的默认初始化值
        //整型数组元素:默认值为0
        //浮点型数组元素:默认值为0.0
        //char型数组元素:默认值为0或'\u000'
        //boolean型数组元素:默认值为false
        //引用数据类型数组元素:默认值为null
    }
}
  • 常用内存结构解析
    第四章  数组_初始化

  • 一维数组内存结构解析

第四章  数组_Java基础_02

3.二维数组的使用
  • Java语言中提供了支持多维数组的语法。
  • 如果说可以把一维数组当成几何中的线性图形,那么二维数组就相当于是一个表格,像Excel表格一样。
  • 对于二维数组的理解,我们可以看作是一维数组array1又作为另一个一维数组array2的元素而存在。其实,从数组底层的运行机制来看,其实并没有多维数组。
/*
    二维数组的理解:
        对于二维数组的理解,我们可以看作是一维数组array1又作为另一个一维数组array2的元素而存在。
        其实,从数组底层的运行机制来看,其实并没有多维数组。
    二维数组的使用:
        1.二维数组的声明和初始化
        2.调用数组指定位置的元素
        3.获取数组的长度
        4.遍历数组
        5.数组元素的默认初始化值
            规定:二维数组分为内层元素和外层元素
                int[][] array = new int[4][3];
                外层元素:array[0]、array[1]等
                内层元素:array[0][0]、array[1][2]等
            针对于初始化方式一:比如:int[][] array = new int[4][3];
                外层元素的初始值为地址值,内层元素的初始值与一维元素的初始值相同
            针对于初始化方式二:比如:int[][] array = new int[3][];
                外层元素的初始值为null,内层元素的初始值会报NullPointerException
        6.数组的内存解析
 */
public class ArrayTest2 {
    public static void main(String[] args) {
        //一维数组的初始化
        int[] array1 = new int[]{1,2,3,4,5};
        //二维数组的静态初始化
        int[][] array2 = new int[][]{{1,2,3},{4,5},{6,7,8}};
        //二维数组的动态初始化
        //方式一:
        String[][] array3 = new String[3][2];
        //方式二:
        String[][] array4 = new String[3][];

        //2.调用数组指定位置的元素
        System.out.println(array2[0][1]);   //结果为2
        System.out.println(array3[1][1]);   //结果为null

        array4[1] = new String[4];//对二维数组进行初始化
        System.out.println(array4[1][0]);   //如果未初始化,会报NullPointerException

        //3.获取数组的长度
        System.out.println(array2.length);      //结果为3
        System.out.println(array2[0].length);   //结果为3
        System.out.println(array2[1].length);   //结果为2
        System.out.println(array2[2].length);   //结果为3

        //4.遍历二维数组
        for (int i = 0;i < array2.length;i++) {
            for(int j = 0;j < array2[i].length;j++) {
                System.out.print(array2[i][j] + "\t");
            }
            System.out.println();
        }

        //5.数组元素的默认初始化值
        int[][] array5 = new int[4][3];
        System.out.println(array5[0]);      //地址值:[I@1540e19d
        System.out.println(array5[0][0]);   //0
        System.out.println(array5);         //地址值:[[I@677327b6

        double[][] array6 = new double[3][];
        System.out.println(array6[1]);  //null
        //System.out.println(array6[1]);    //NullPointerException
    }
}
  • 二维数组内存结构的解析第四章  数组_数组元素_03
4.数组中的常见算法

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

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

/*
    算法的考查:求数值型数组中元素的最大值、最小值、平均数、总和等

    要求:定义一个int型的一维数组,包含10个元素,分别赋一个随机整数
    然后求出所有元素的最大值、最小值、平均值和总和,并输出出来
    所有随机值都是两位数

    [10-99]
    公式:(int)(Math.random() * (99-10+1) + 10)
 */
public class ArrayTest {
    public static void main(String[] args) {
        //数组的初始化
        int[] array = new int[10];
        //给数组元素随机赋值
        for(int i = 0;i < array.length;i++) {
            array[i] = (int)(Math.random() * (99-10+1) + 10);
        }

        //数组元素的遍历
        for(int i = 0;i < array.length;i++) {
            System.out.print(array[i] + "\t");
        }
        System.out.println();
        
        //求数组元素的最大值
        int maxValue = array[0];
        for(int i = 1;i < array.length;i++) {
            if(maxValue < array[i]) {
                maxValue = array[i];
            }
        }
        System.out.println("最大值为:" + maxValue);

        //求数组元素的最小值
        int minValue = array[0];
        for(int i = 1;i < array.length;i++) {
            if(minValue > array[i]) {
                minValue = array[i];
            }
        }
        System.out.println("最小值为:" + minValue);

        //求数组元素的总和
        int sum = 0;
        for (int i = 0;i < array.length;i++) {
            sum = sum + array[i];
        }
        System.out.println("总和为:" + sum);

        //求数组元素的平均值
        double avgValue = sum / array.length;
        System.out.println("平均值为:" + avgValue);

    }
}

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

/*
    算法的考查:数组的复制、反转
 */
public class ArrayTest1 {
    public static void main(String[] args) {
        String[] array1 = new String[]{"DD","MM","GG","JJ","AA"};
        //数组的复制
        String[] array2 = new String[array1.length];
        for(int i = 0;i < array1.length;i++) {
            array2[i] = array1[i];
        }

        //数组元素的遍历
        for(int i = 0;i < array2.length;i++) {
            System.out.print(array2[i] + "\t");
        }
        System.out.println();

        //数组元素的反转
        for(int i = 0;i < array1.length / 2;i++) {
            String temp = array1[i];
            array1[i] = array1[array1.length - i - 1];
            array1[array1.length - i - 1] = temp;
        }

        for(int i = 0;i < array1.length;i++) {
            System.out.print(array1[i] + "\t");
        }
    }
}
/*
    数组元素的查找:线性查找和二分查找
 */
public class ArrayTest2 {
    public static void main(String[] args) {
        String[] array1 = new String[]{"DD","MM","GG","JJ","AA"};

        String dest = "BB";
        boolean isFlag = true;
        //线性查找
        for(int i = 0;i < array1.length;i++) {
            if(dest.equals(array1[i])) {
                System.out.println("找到了指定的元素,位置为:" + i);
                isFlag = false;
                break;
            }
        }
        if(isFlag) {
            System.out.println("很遗憾,没有找到指定的元素");
        }

        //二分查找
        //要求查找的数组元素必须有序
        int[] array2 = new int[]{-2,8,25,46,78,96,103};
        int head = 0;//头索引
        int end = array2.length - 1;
        int dest1 = 25;
        boolean isFlag1 = true;
        while(head <= end) {
            int middle = (head + end) / 2;
            if(dest1 == array2[middle]) {
                System.out.println("找到了指定的元素,位置为:" + middle);
                isFlag1 = false;
                break;
            } else {
                //当目标元素值大于中间索引元素的值
                if(dest1 > array2[middle]) {
                    //head索引往后移
                    head = middle + 1;
                    //当目标元素值小于中间索引元素的值
                } else {
                    //end往前移
                    end = middle - 1;
                }
            }
        }
        if(isFlag1) {
            System.out.println("很遗憾,没有找到指定的元素");
        }
    }
}

4.4 数组元素的排序算法

  • 排序:假设含有n个记录的序列为{R1,R2,...,Rn},其对应的关键字序列为{K1,K2,...,Kn}。给这些记录重新排序为{Ri1,Ri2,...,Rin},使用相应的关键字值条件满足Ki1<=Ki2<=...<=Kin,这样的一种操作称为排序。

    通常来说,排序的目的是快速查找

  • 衡量排序算法的优劣:
    1.时间复杂度:分析关键字的比较次数和记录的移动次数
    2.空间复杂度:分析排序算法中需要多少辅助空间
    3.稳定性:如果两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的.

  • 排序算法的分类:
    1.内部排序
    2.外部排序

  • 十大内部排序算法:

    • 选择排序
      1.直接选择排序、堆排序
    • 交换排序
      1.冒泡排序快速排序
    • 插入排序
      1.直接插入排序、折半插入排序、Shell排序
    • 归并排序
    • 桶式排序
    • 基数排序
/*
    冒泡排序的实现:
 */
public class BubbleSortTest {
    public static void main(String[] args) {
        int[] array = new int[]{43,32,65,-8,12,-7,0,9,98};
        //控制轮数
        for(int i = 0;i < array.length - 1;i++) {
            //控制每一轮的次数
            for(int j = 0;j < array.length - 1 - i;j++) {
                if(array[j] > array[j+1]) {
                    int temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
        }

        //遍历数组元素
        for(int i = 0;i < array.length;i++) {
            System.out.print(array[i] + "\t");
        }
    }
}
5.Arrays工具类的使用

java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法。

第四章  数组_初始化_04

/*
    数组工具类的使用:
 */
public class ArraysTest {
    public static void main(String[] args) {
        //1.判断两个数组是否相等
        int[] array1 = new int[]{1,2,3,4};
        int[] array2 = new int[]{1,3,2,4};
        int[] array3 = new int[]{2,6,15,19,30,36,45,60};
        boolean b = Arrays.equals(array1,array2);
        System.out.println(b);

        //2.输出数组信息
        String s = Arrays.toString(array1);
        System.out.println(s);

        //3.将指定值填充到数组当中
        Arrays.fill(array1,10);
        System.out.println(Arrays.toString(array1));

        //4.对数组元素进行排序
        Arrays.sort(array2);
        System.out.println(Arrays.toString(array2));

        //5.二分查找
        int count = Arrays.binarySearch(array3,36);
        System.out.println(count);
    }
}