Java数组

1 - 数组的概念

数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过

编号的方式对这些数据进行统一管理。

2 - 数组的常见概念

①数组名

②下标(或索引)

③元素

④数组的长度:元素的个数

3 - 数组的特点

1.数组是有序排列的

2.数组属于引用类型的变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型

3.创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址

4.数组的长度一旦确定,就不能修改

5.我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快

4 - 数组的分类

1.按照维度:一维数组,二维数组,三维数组

2.按照元素的数据类型分:基本数据类型元素的数组,引用数据类型元素的数组

5 - 一维数组的使用

public class ArrayTest {

    public static void main(String[] args) {
        // 1.一维数组的声明和初始化
        int num; // 声明
        num = 10; // 初始化
        int id = 1001; // 声明 + 初始化
        
        int[] ids; // 声明
        ids = new int[]{1,2,3};// 1-静态初始化:初始化和数组元素的赋值操作同时进行
        
        String[] names = new String[5]; // 2-动态初始化:初始化和数组元素的赋值操作分开进行
        
        // 错误写法
        // int[] array1 = new int[];
        // int[5] array2 = new int[];
        // int[] array3 = new int[3]{1,2,3};
        
        // 总结:数组一旦初始化完成,其长度就确定了
        
        // 2.如何调用数组的指定位置的元素:通过角标的方式调用。
        // 数组的角标(或索引)从0开始的,到数组的长度-1结束。
        names[0] = "韩信";
        names[1] = "李白";
        names[2] = "张飞";
        names[3] = "貂蝉";
        names[4] = "守约";
        
        // 3.如何获取数组的长度
        // 属性:length
        System.out.println(names.length); // 5
        
        // 4.如何遍历数组
         for(int i = 0;i < names.length;i++){
             System.out.println(names[i]);
         }
         
         // 5.数组元素的默认初始化值
             // >数组元素是整型:0
         short[] s1 = new short[2];
             // >数组元素是浮点型:0.0
         float[] f1 = new float[2];
            // >数组元素是char型:0'u0000',而非'0'
         char[] c1 = new char[2];
             // >数组元素是boolean型:false
         boolean[] b1 = new boolean[5];
             // >数组元素是引用数据类型:null
         String[] arry = new String[5];

6 - 数组的内存解析

1-内存结构

 2-数组内存解析

 

7 - 一维数组练习题

题目1:从键盘读入学生成绩,找出最高分,并输出学生的成绩等级。A级 -(成绩 >= 最高分 - 10),B级-(成绩 >= 最高分 -20),C级-(成绩 >=最高分 - 30),其余的为D级。

import java.util.Scanner;
public class Test1 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        System.out.print("请输入学生人数:");
        int studentNumber = scan.nextInt(); // 接收数组长度
        int[] studentArray = new int[studentNumber];
        System.out.println("请输入"+studentNumber+"个学生的考试成绩:");

        for(int i = 0;i < studentArray.length;i++){
            studentArray[i] = scan.nextInt();
        }
        int max = 0;
//        if(studentArray[0] > studentArray[1]){
//            max = studentArray[0];
//        }else{
//            max = studentArray[1];
//        }
        for(int i = 0;i < studentArray.length;i++){
            if(max < studentArray[i]){
                max = studentArray[i];
            }
        }
        System.out.println("最高分是"+max);
        String level = "";
        for(int i = 0;i < studentArray.length;i++){
            if(studentArray[i] >= max-10){
                level = "A";
            }else if(studentArray[i] >= max-20){
                level = "B";
            }else if(studentArray[i] >= max-30){
                level = "C";
            }else{
                level = "D";
            }
            System.out.println("Student"+i+"score is"+studentArray[i]+",grade is"+level);
        }
    }
}
View Code

8 - 二维数组的使用

1-Java语言里提供了支持多维数组的语法
2-如果说可以把一维数组当成几何中的线性图形,那么二维数组就相当于是一个表格就像Excel表格一样
3-对于二维数组的理解,我们可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。其实,从数组底层的运行机制来看,其实没有多维数组。

/*
* 二维数组的使用
1-理解:
    对于二维数组的理解,我们可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。其实,
    从数组底层的运行机制来看,其实没有多维数组。
2-二维数组的使用
    ①一维数组的声明和初始化
    ②如何调用数组的指定位置的元素
    ③如何获取数组的长度
    ④如何遍历数组
    ⑤数组元素的默认值初始化值
    ⑥数组的内存解析
 */
public class Test2 {
    public static void main(String[] args){
        // 1.二维数组的声明和初始化
        int[] array1 = new int[]{1,2,3}; // 一维数组    int[] array1 = {1,2,3}; 类型推断
        // 静态初始化
        int[][] array2 = new int[][]{{1,2},{10,20,30},{17,50}};
        // 动态初始化
        String[][] array3 = new String[3][2]; // 相当于 3行 2列
        // String array3[][] = new String[3][2];
        // 错误写法举例
        // String[][] array4 = new String[][2];
        // String[][3] array5 = new String[1][2];

        // 2.如何调用数组的指定位置的元素
        String[][] array4 = new String[][]{{"韩信","李白","刘备"},{"李信","花木兰"},{"后裔"},{"王昭君","貂蝉"}};
        // 输出最帅的打野英雄-李白
        System.out.println(array4[0][1]); // 李白
        // 输出最美的中路英雄-王昭君
        System.out.println(array4[3][0]); // 王昭君

        // 3.获取数组的长度
        System.out.println(array4.length); // 4
        System.out.println(array4[0].length); // 3

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

9 - 二维数组元素的默认值初始化值

/*
 * 规定:二维数组分为外侧数组的元素,内层数组的元素
 * int[][] arr = new int[4][3];
 * 外侧元素:arr[0],arr[1]等
 * 内层元素:arr[0][0],arr[1][2]等
 * 
 * 数组元素的默认初始化值
 * 针对于初始化方式1:比如:int[][] arr = new int[4][3];
 *         外侧元素的初始化值为:地址值
 *         内层元素的初始化值为:与一维数组初始化情况相同
 * 针对于初始化方式2:比如:int[][] arr = new int[4][];
 *         外侧元素的初始化值为:地址值
 *         内层元素的初始化值为:不能调用,否则报错
 * 
 */
    
public class ArrayTest3 {

    public static void main(String[] args) {
        // 数组元素的默认值初始化值
        int[][] array1 = new int[4][3]; // ①数组元素是int
        System.out.println(array1[0]); // 地址值
        System.out.println(array1[0][0]); // 0
        
        float[][] array2 = new float[4][3]; // ②数组元素是float
        System.out.println(array2[0]); // 地址值
        System.out.println(array2[0][0]); // 0.0
        
        String[][] array3 = new String[2][4]; // ③数组元素是String
        System.out.println(array3[0]); // 地址值
        System.out.println(array3[0][0]); // null
        
        String[][] array4 = new String[4][];
        System.out.println(array4[0]); // null
        // System.out.println(array4[0][0]); // 报错
        
    }
}
View Code

10 - 二维数组元素的内存解析与杨辉三角的实现

 

练习:杨辉三角的实现(打印10行杨辉三角)

 

 @Test
    public void testYannghui(){
        // 打印10行杨辉三角(yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j])
        // 1. 声明并初始化二维数组
        int[][] yanghui = new int[10][];
        // 2. 给数组元素赋值
        for(int i = 0;i < yanghui.length;i++){
            yanghui[i] = new int[i + 1];
            // 2.1给首末元素赋值
            yanghui[i][0] = yanghui[i][i] = 1;
            // 2.2给每行的非首末元素赋值
            if(i > 1){
                for(int j = 1;j < yanghui[i].length - 1;j++){
                    yanghui[i][j] = yanghui[i - 1][j - 1] + yanghui[i -1][j];
                }
            }
        }
        // 3. 遍历二维数组
        for(int i = 0;i < yanghui.length;i++){
            for(int j = 0;j < yanghui[i].length;j++){
                System.out.print(yanghui[i][j] + " ");
            }
            System.out.println();
        }
    }
打印杨辉三角

 

11 - 数组中涉及的常见算法

1-算法的考查:求数值型数组中元素的最大值,最小值,平均数,总和等

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

public class Test3 {
    public static void main(String[] args){
        int[] array1 = new int[10];
        for(int i = 0;i < array1.length;i++){
            array1[i] = (int)(Math.random() * (99-10+1) + 10);
            System.out.print(array1[i]+" ");
        }
        System.out.println();
        // 求数组的最大值
        int maxNumber = array1[0];
        for(int i = 1;i < array1.length;i++){
            if(maxNumber < array1[i]){
                maxNumber = array1[i];
            }
        }
        System.out.println("最大值为"+maxNumber);
        // 求数组的最小值
        int minNumber = array1[0];
        for(int i = 1;i < array1.length;i++){
            if(minNumber > array1[i]){
                minNumber = array1[i];
            }
        }
        System.out.println("最大值为"+minNumber);
        // 求数组的所有元素和
        int sum = 0;
        for(int i = 0;i < array1.length;i++){
            sum += array1[i];
        }
        System.out.println("总和为"+sum);
        // 求数组的平均值
        double avg = sum/array1.length;
        System.out.println("平均数为"+avg);
    }
}
View Code

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

/*
使用简单的数组
①创建一个名为ArrayExer2的类,在main()方法中声明array1和array2两个变量他们是int[]类型的数组。
②使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19
③显示array1的内容
④赋值array2变量等于array1,修改array1中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。打印出array1.

思考:array1和array2是什么关系。 array1和array2地址值相同,都指向了对空间的唯一的数组实体
扩展:修改题目,实现array2 对 array1 的复制
 */
public class ArrayExer2{
    public static void main(String[] args){
        // 1.声明array1和array2两个变量他们是int[]类型的数组。
        int[] array1,array2;
        // 2.把array1初始化为8个素数:2,3,5,7,11,13,17,19
        array1 = new int[]{2,3,5,7,11,13,17,19};
        // 3.显示array1的内容
        for(int i = 0;i < array1.length;i++){
            System.out.print(array1[i]+"\t");
        }
        System.out.println();
        // 4.赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。打印出array1
        array2 = array1; // 不能称作数组的复制
        for(int i = 0;i < array2.length;i++){
            if(i % 2 == 0){
                array2[i] = i; // 修改array2
            }
            System.out.print(array1[i]+"\t"); // 打印array1
        }
        System.out.println();

        // 扩展:真正实现数组的复制 实现两个数组完全独立
        int[] array3 = new int[]{2,3,5,7,11,13,17,19};
        int[] array4 = new int[array3.length];

        for(int i = 0;i < array3.length;i++){
            array4[i] = array3[i];
            System.out.print(array4[i]+"\t");
        }
        System.out.println();
        for(int i = 0;i < array3.length;i++){
            System.out.print(array3[i]+"\t");
        }
    }
}
复制(浅拷贝)
/*
数组的反转
 */
public class Test3{
    public static void main(String[] args){
        // 数组的反转
        String[] array1 = new String[]{"e","d","c","b","a"};
        String temp = "";
        for(int i = 0;i < array1.length / 2;i++){
            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 Test3 {
    public static void main(String[] args) {
        // 线性查找
        // 找出 李白
        String[] strArray = new String[]{"a", "b", "c", "d", "李白"};
        String dest = "李白";
        boolean tag = false;
        for (int i = 0; i < strArray.length; i++) {
            // equals() 方法 判断两个String类型元素的值是否相等
            if (dest.equals(strArray[i])) {
                System.out.println("找到了指定的元素,位置为" + i);
                tag = true;
                break;
            }
        }
        if(tag == false){
            System.out.println("找不到此元素!");
        }
    }
}
查找(或搜索)
/*
数组的查找(或搜索)
 */
public class Test3 {
    public static void main(String[] args) {
        // 二分法查找
        // 前提:所要查找的数组必须有序
        int[] numberArray = new int[]{1,2,3,10,20,30,55,60,425,785};
        int dest = 55; // 假设查找55
        int head = 0; // 初始的首索引
        int end = numberArray.length - 1; // 初始的末索引
        boolean isFlag = true;
        while(head <= end){
            int middle = (head+end)/2;
            if(dest == numberArray[middle]){
                System.out.println("找到了指定的元素,索引位置为"+middle);
                isFlag = false;
                break;
            }else if(dest > numberArray[middle]){
                head = middle + 1;
            }else{
                end = middle - 1;
            }
        }
        if(isFlag){
            System.out.println("找不到指定的元素!");
        }
    }
}
二分法查找

3-数组元素的排序算法

排序算法
1-通常来说,排序的目的是快速查找(如排好序后,用二分法查找,可大大提高查找效率)
2-衡量排序算法的优劣
    ①时间复杂度:分析关键字的比较次数和记录的移动次数
    ②空间复杂度:分析排序算法中需要多少辅助内存
    ③稳定性:若两个记录A和B的关键字值相等,但排序后A,B的先后次序保持不变,则称这种排序算法是稳定的。
3-排序算法的分类:内部排序和外部排序
    内部排序:整个排序过程不需要借助外部存储器(如磁盘等),所有排序操作都在内存中完成。
    外部排序:参与排序的数据非常多,数据量非常大,计算机无法把整个排序过程放在内存中完成,必须借助于外部存储器(如磁盘)
    。外部排序最常见的是多路归并排序。可以认为外部排序是由多次内部排序组成。
4-10大内部排序算法
    ①选择排序
        直接选择排序,堆排序
    ②交换排序
        冒泡排序,快速排序
    ③插入排序
        直接插入排序,折半插入排序,shell排序
    ④归并排序
    ⑤桶式排序
    ⑥基数排序
 */
排序算法介绍
/*
数组冒泡排序的实现
 */
public class Test3 {
    public static void main(String[] args) {
        int[] array1 = new int[]{42,54,1,3,58,10,100,21,36};
        for(int i = 0;i < array1.length -1;i++){
            for(int j = 0;j < array1.length - i - 1;j++){
                if(array1[j] > array1[j+1]){
                    int temp = array1[j];
                    array1[j] = array1[j+1];
                    array1[j+1] = temp;
                }
            }
        }
        for(int i =0;i < array1.length;i++){
            System.out.print(array1[i]+"\t");
        }
    }
}
冒泡排序
/*
 * 快速排序
1-快速排序通常明显比同为O(nlongn)的其他算法更快,因此常被采用,而且快速排序采用了分治法的思想,所以在很多笔试面试中
能经常看到快排的影子,可见掌握快排的重要性。
2-快速排序(Quick Sort)由图灵奖获得者Tony Hoare 发明,内列为20世纪十大算法之一,迄今为止所有内排序算法中速度最快的一种。冒泡排序
的升级版,交换排序的一种,快速排序的时间复杂度为O(nlog(n).
 */
public class Test3 {
    public static void main(String[] args) {
        // 快速排序的实现
        // 代码有点难
    }
}
快速排序

12 - 算法的五大特征

13 - 操作数组常用的工具类

import java.util.Arrays;

/*
java.util.Arrays:操作数组的工具类,里面定义了很多操作数组的方法
 */
public class ArraysTest {
    public static void main(String[] args){

        // 1.boolean equals(int[] a,int[] b) 判断两个数组是否相等
        int[] array1 = new int[]{1,2,3,4};
        int[] array2 = new int[]{4,3,2,1};
        boolean isEquals = Arrays.equals(array1,array2);
        System.out.println(isEquals);

        // 2.String toString(int[] a) 输出数组的信息
        System.out.println(Arrays.toString(array1)); // [1, 2, 3, 4]

        // 3.void fill(int[] a,int val) 将指定的值填充到数组中
        Arrays.fill(array2,10);
        System.out.println(Arrays.toString(array2)); // [10, 10, 10, 10]

        // 4.void sort(int[] a) 对数组排序
        int[] array3 = new int[]{21,30,11,50,1,2};
        Arrays.sort(array3);
        System.out.println(Arrays.toString(array3));

        // 5.int binarySearch(int[] a,int key) 对排好序的数组用二分法进行检索指定的值
        int[] array4 = new int[]{1,2,11,21,30,50};
        int index = Arrays.binarySearch(array4,30);
        if(index > 0){
            System.out.println(index);
        }else{
            System.out.println("未找到");
        }
    }
}
代码示例

14 - 数组使用中常见的异常

/*
数组使用中常见的异常:
    1.数组角标越界的异常  ArrayIndexOutOfBoundsException
    2.空指针异常  NullPointerException
 */
public class ArrayExceptionTest {
    public static void main(String[] args){
        // 1.数组角标越界的异常  ArrayIndexOutOfBoundsException
        int[] array1 = new int[]{1,2,3};
        System.out.println(array1[3]);
        /*
        Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
            at arrays.test.ArrayExceptionTest.main(ArrayExceptionTest.java:11)
         */

        // 2.空指针异常  NullPointerException
        // 情况1
        int[] array2 = new int[]{1,2,3};
        array2 = null;
        System.out.println(array2[0]);
        /*
        Exception in thread "main" java.lang.NullPointerException
            at arrays.test.ArrayExceptionTest.main(ArrayExceptionTest.java:20)
         */
        // 情况2
        int[][] array3 = new int[4][];
        System.out.println(array3[0]); // null
        System.out.println(array3[0][1]); // 报错

        // 情况3
        String[] array4 = new String[]{"aa","bb","cc"};
        array4[0] = null;
        System.out.println(array4[0].toString());
    }
}
常见的异常

 

posted @ 2020-05-26 16:54  赖正华  阅读(165)  评论(0编辑  收藏  举报