day05

day05,第1张

day05

容器概念

  • 容器:是将多个数据存储到一起,每个数据称为该容器的元素。生活中的容器:水杯,衣柜,教室

数组的概述

  • 数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式 对这些数据进行统一管理。 数组就是用于存储数据的长度固定的容器。

百度百科中对数组的定义:

所谓数组(array),就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,以便统一管理他们,然后用编号区分他们,这个名字称为数组名,编号称为下标或索引(index)。组成数组的各个变量称为数组的元素(element)。组中元素的个数称为数组的长度(length)。

特点:

  • 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
  • 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
  • 数组的长度一旦确定,就不能修改。
  • 我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快。

数组的分类:

  • 按照维度:一维数组、二维数组、三维数组、…
  • 按照元素的数据类型分:基本数据类型元素的数组、引用数据类型元素的数组(即对象数组)
一维数组

一维数组的声明格式有以下两种:

  • 数组元素的类型[ ] 变量名称;
  • 数组元素的类型 变量名称[ ];

数组元素的类型,可以是 java 中的任意类型,变量名称可以是任意合法的标识符,上面两种格式推荐是第一种,例如:

int [ ] a;
Student[ ] stu
int[ ] a, b, c  // 在一行中也可以声明多个数组

我们单单在程序中声明了数据,而不给他初始化是无法使用的。数组的初始化:在内存当中创建一个数组,并且向其中赋予一些默认值。两种常见的初始化方式:

  • 动态初始化(指定长度):在创建数组的时候,直接指定数组当中的数据元素个数。
  • 静态初始化(指定内容):在创建数组的时候,不直接指定数据个数多少,而是直接将具体的数据内容进行指定。

动态初始化数组的格式:

  • 数据类型[ ] 数组名称 = new 数据类型[数组长度];

解析含义:

  • 左侧数据类型:创建的数组容器可以存储什么数据类型的数据。 元素的类型可以是任意的Java的数据类型。例如:int, String, Student等
  • 左侧的中括号[ ] :代表我是一个数组
  • 左侧数组名称:为定义的数组起个变量名,满足标识符规范,可以使用名字 *** 作数组。
  • 右侧的new:代表创建数组的动作。关键字,创建数组使用的关键字。因为数组本身是引用数据类型,所以要用new创建数组对象。
  • 右侧数据类型:必须和左边的数据类型保持一致
  • 右侧中括号的长度:也就是数组当中,到底可以保存多少个元素 ,是一个int数字。

代码示例

        // 创建一个数组,里面可以存放300个int数据
        int[] arrayA = new int[300];

        // 创建一个数组,能存放10个double类型的数据
        double[] arrayB = new double[10];

        // 创建一个数组,能存放5个字符串
        String[] arrayC = new String[5];

静态初始化基本格式:

  • 数据类型[] 数组名称 = new 数据类型[] { 元素1, 元素2, ... };
       // 直接创建一个数组,里面装的全都是int数字,具体为:5、15、25
        int[] arrayA = new int[] { 5, 15, 25, 40 };

        // 创建一个数组,用来装字符串:"Hello"、"World"、"Java"
        String[] arrayB = new String[] { "Hello", "World", "Java" };

静态初始化省略格式:

  • 数据类型[ ] 数组名称 = { 元素1, 元素2, ... };
 // 省略格式的静态初始化
 int[] arrayA = { 10, 20, 30 };

注意事项:

  • 静态初始化没有直接指定长度,但是仍然会自动推算得到长度。
  • 静态初始化标准格式可以声明和赋值分开进行
  • 动态初始化也可以声明和赋值分开进行
  • 静态初始化一旦使用省略格式,就不能声明和赋值分开进行
  • 如果不确定数组当中的具体内容,用动态初始化;否则,已经确定了具体的内容,用静态初始化。

代码示例

public class Demo03Array {
    public static void main(String[] args) {
        // 静态初始化的标准格式,声明和赋值分开进行
        int[] arrayB;
        arrayB = new int[] { 11, 21, 31 };

        // 动态初始化也可以拆分成为两个步骤,声明和赋值分开进行
        int[] arrayC;
        arrayC = new int[5];

        // 静态初始化的省略格式,声明和赋值分开进行
        //  int[] arrayD;
        // arrayD = { 10, 20, 30 };
    }

}

如何调用数组的指定位置的元素

  • 索引:每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引 (index),特点:连续,逐一增加,每次加1。
  • 可以通过数组的索引访问到数组中的元素。 格式:数组名[索引]
  • 也可以通过数组的索引给数组指定位置赋值
  • 数组元素下标可以是整型常量或整型表达式。如a[3] , b[i] , c[6*i];
  • 数组元素下标从0开始;长度为n的数组合法下标取值范围: 0到 n-1。

代码示例

public class Demo04ArrayUse {

    public static void main(String[] args) {
        // 静态初始化的省略格式
        int[] array = { 10, 20, 30 };

        System.out.println(array); // [I@75412c2f

        // 直接打印数组当中的元素
        System.out.println(array[0]); // 10
        System.out.println(array[1]); // 20
        System.out.println(array[2]); // 30
        System.out.println("=============");

        // 也可以将数组当中的某一个单个元素,赋值交给变量
        int num = array[1];
        System.out.println(num); // 20
    }

}

如何获取数组的长度

  •  每个数组都具有长度,而且是固定的,Java中赋予了数组的一个属性,可以获取到数组的长度,语法: 数组名.length ,属性length的执行结果是数组的长度,int类型结果。由次可以推断出,数 组的最大索引值为数组名.length-1

代码示例

public class Demo03ArrayLength {

    public static void main(String[] args) {
        int[] arrayA = new int[3];

        int[] arrayB = {10, 20, 30, 3, 5, 4, 6, 7, 8, 8, 65, 4, 44, 6, 10, 3, 5, 4, 6, 7, 8, 8, 65, 4};
        int len = arrayB.length;
        System.out.println("arrayB数组的长度是:" + len);
        System.out.println("=============");

        int[] arrayC = new int[3];
        System.out.println(arrayC.length); // 3
        arrayC = new int[5];
        System.out.println(arrayC.length); // 5
    }

}

如何遍历数组

代码示例


public class Demo07Array {
    
    public static void main(String[] args) {
        int[] arr = {11, 22, 33, 44, 55};

        // 数组名.length
        System.out.println("arr数组中元素的个数为:" + arr.length);
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

 增强for 遍历数组,代码示例


public class Demo03 {
    public static void main(String[] args) {
        String [] strArr = new String[]{"蔡旭坤","特朗普","肖战","郭德纲"};
        for (String s : strArr) {
            System.out.print(s+ " ");//蔡旭坤 特朗普 肖战 郭德纲 
        }
    }
}

 一维数组元素的默认初始化值

  • 数组是引用类型,它的元素相当于类的成员变量,因此数组一经 分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化。
  • 对于基本数据类型而言,默认初始化值各有不同
  • 对于引用数据类型而言,默认初始化值为null(注意与0不同!)       

代码示例

public class Demo {
    public static void main(String[] args) {
        // 动态初始化一个数组
        int[] array = new int[3];
        Object[] objects = new Object[4];
        System.out.println(array); // 内存地址值
        System.out.println(array[0]); // 0
        System.out.println(objects[0]);//null
    }
}
Java虚拟机的内存划分

为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。 JVM的内存划分如下图所示:

 注意事项:

  • 每new一次就必定会在堆空间开辟一个新的空间
  • 数组的变量名称存在于栈空间中。而且保存了存储在数组中的首地址

一个数组的内存图

多个数组指向相同内存图

代码示例

public static void main(String[] args) {
    // 定义数组,存储3个元素
    int[] arr = new int[3];
    //数组索引进行赋值
    arr[0] = 5;
    arr[1] = 6;
    arr[2] = 7;
    //输出3个索引上的元素值
    System.out.println(arr[0]);
    System.out.println(arr[1]);
    System.out.println(arr[2]);
    //定义数组变量arr2,将arr的地址赋值给arr2
    int[] arr2 = arr;
    arr2[1] = 9;
    System.out.println(arr[1]);
}

结论:引用类型传递的是内存地址值

需求:在编程竞赛中,有6个评委为参赛的选手打分,分数为0-100的整数分。选手的最后得分为:去掉一个最高分和一个最低分后 的4个评委平均值 (不考虑小数部分)。

import java.util.Scanner;

public class Test5Array {
    
    public static void main(String[] args) {
        // 1.定义一个数组,用动态初始化完成数组元素的初始化,长度为6
        int[] arr = new int[6];
        // 2.键盘录入评委分数
        Scanner sc = new Scanner(System.in);
        //  3.由于是6个评委打分,所以,接收评委分数的 *** 作,用循环
        for (int i = 0; i < arr.length; i++) {
            System.out.println("请输入第" + (i+1) + "个评委的打分:");
            int score = sc.nextInt();
            if(score >= 0 && score <= 100){
                // 合法的分值
                arr[i] = score;
            }else{
                // 非法的分值
                System.out.println("您的打分输入有误, 请检查是否是0-100之间的");
                i--;
            }
        }

        // 4.求出数组最大值
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if(max < arr[i]){
                max = arr[i];
            }
        }

        // 5.求出数组最小值
        int min = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if(min > arr[i]){
                min = arr[i];
            }
        }

        // 6.求出数组总和
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }

        // 7.按照计算规则进行计算得到平均分
        int avg = (sum - max - min ) / 4;

        // 8.输出平均分
        System.out.println(avg);
    }
}
二维数组

对于二维数组的理解,我们可以看成是一维数组 array1又作为另一个一维数组array2的元素而存在。其实,从数组底层的运行机制来看,其实没有多维数组。

二维数组的声明格式如下:

 注意:

int[] x, y[];
//x是一维数组,y是二维数组

和一维数组一样,如果只声明不赋值是不能使用的。下面介绍几种二维数组初始化的方式:

静态初始化

 如果是静态初始化,右边new 数据类型[ ][ ]中不能写数字,因为行数和列数,由{ }的元素个数决定



class Test4{

    public static void main(String [] args){
        int [][] arr = new int[5][6];
        //查找第一个一维数组的长度
        
        System.out.println(arr.length);
        
        System.out.println("--->"+arr[0].length);
        //获取第一个一维数组内第二个元素
        System.out.println("--->"+arr[0][1]);//0
        
        System.out.println("--->"+arr[1].length);
        System.out.println("--->"+arr[2].length);
        System.out.println("--->"+arr[3].length);
        System.out.println("--->"+arr[4].length);
        
        System.out.println("--------------------------------------------------");//0
        
        
        
        double [][] doubleArr = new double[3][];
        
        System.out.println(doubleArr.length);
        //静态初始化给第一个一维数组赋值
        doubleArr[0] = new double[]{3.14,6.28};
        
        //Exception in thread "main" java.lang.NullPointerException
        System.out.println(doubleArr[0][0]);
        
        //动态初始化 给第二个一维数组赋值
        doubleArr[1] = new double[5];
        System.out.println(doubleArr[1][2]);
        
        
        
    }
}

​动态初始化(规则二维表:每一行的列数是相同的)

 代码示例

public class Demo10Array {
    public static void main(String[] args) {
        //定义一个二维数组
        int[][] arr = new int[3][2];

        //定义了一个二维数组arr
        //这个二维数组有3个一维数组的元素
        //每一个一维数组有2个元素
        //输出二维数组名称
        System.out.println(arr); //地址值    [[I@175078b

        //输出二维数组的第一个元素一维数组的名称
        System.out.println(arr[0]); //地址值    [I@42552c
        System.out.println(arr[1]); //地址值    [I@e5bbd6
        System.out.println(arr[2]); //地址值    [I@8ee016

        //输出二维数组的元素
        System.out.println(arr[0][0]); //0
        System.out.println(arr[0][1]); //0
    }
}

动态初始化(不规则:每一行的列数可能不一样)

 代码示例

​public class Demo11Array {
    public static void main(String[] args) {
        //定义数组
        int[][] arr = new int[3][];

        System.out.println(arr);    //[[I@175078b

       //  System.out.println(arr[1][0]); NullPointerException
        System.out.println(arr[0]); //null
        System.out.println(arr[1]); //null
        System.out.println(arr[2]); //null

        //动态的为每一个一维数组分配空间
        arr[0] = new int[2];
        arr[1] = new int[3];
        arr[2] = new int[1];

        System.out.println(arr[0]); //[I@42552c
        System.out.println(arr[1]); //[I@e5bbd6
        System.out.println(arr[2]); //[I@8ee016

        System.out.println(arr[0][0]); //0
        System.out.println(arr[0][1]); //0
        //ArrayIndexOutOfBoundsException
        //System.out.println(arr[0][2]); //错误

        arr[1][0] = 100;
        arr[1][2] = 200;
    }
}

 如何调用数组的指定位置的元素

 //  定义一个名称为arr的二维数组,二维数组中有三个一维数组
        //  每一个一维数组中具体元素也都已初始化
        String[][] arr = new String[][]{{"a", "b", "c"}, {"e", "f"}, {"w", "|", "wed", "|wre"}};
        //找到二维数组中的index为0一维数组 arr[0]
        //访问一维数组index 为2 第三个元素
        System.out.println(arr[2][3]); //|wre

  获取数组的长度

public class Demo0 {
    public static void main(String[] args) {
        //  定义一个名称为arr的二维数组,二维数组中有三个一维数组
        //  每一个一维数组中具体元素也都已初始化
        String[][] arr = new String[][]{{"a", "b", "1","c"}, {"e", "f"}, {"w", "|", "wed", "|wre"}};
        //获取二维数组中一维数组的个数
        System.out.println(arr.length);//3
        //获取第一个一维数组的元素个数
        System.out.println(arr[0].length); //4 

    }
}

 如何遍历二维数组

public class Demo0 {
    public static void main(String[] args) {
        //  定义一个名称为arr的二维数组,二维数组中有三个一维数组
        //  每一个一维数组中具体元素也都已初始化
        String[][] arr = new String[][]{{"a", "b", "1","c"}, {"e", "f"}, {"w", "|", "wed", "|wre"}};
        //获取二维数组中一维数组的个数
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j]+ "  ");
            }
            System.out.println(" ");
        }
    }
}

二维数组中保存的是一维数组的地址值

 求二维数组中的最大值和最小值 

public class Demo12Array {
    public static void main(String[] args) {
                int [][] arr = {{10,20,30},{1,2000,3},{-100,200,300}};

                //假设第一个一维数组的第一个元素是最大值
                int maxNum = arr[0][0];//10
                //假设第一个一维数组的第一个元素是最小值
                int minNum = arr[0][0];

                for(int i = 0;imaxNum){

                            maxNum = arr[i][j];

                        }

                        //如果一个数比最小值还小 则 此数是最小值

                        if(arr[i][j] 
Arrays工具类 

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

 代码示例

import java.util.Arrays;


public class ArraysTest {
    public static void main(String[] args) {
        
        //1.boolean equals(int[] a,int[] b):判断两个数组是否相等。
        int[] arr1 = new int[]{1,2,3,4};
        int[] arr2 = new int[]{1,3,2,4};
        boolean isEquals = Arrays.equals(arr1, arr2);
        System.out.println(isEquals);
        
        //2.String toString(int[] a):输出数组信息。
        System.out.println(Arrays.toString(arr1));
        
            
        //3.void fill(int[] a,int val):将指定值填充到数组之中。
        Arrays.fill(arr1,10);
        System.out.println(Arrays.toString(arr1));
        

        //4.void sort(int[] a):对数组进行排序。
        Arrays.sort(arr2);
        System.out.println(Arrays.toString(arr2));
        
        //5.int binarySearch(int[] a,int key)
        int[] arr3 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
        int index = Arrays.binarySearch(arr3, 210);
        if(index >= 0){
            System.out.println(index);
        }else{
            System.out.println("未找到");
        }
        
        
    }
}

注意事项:

  • 索引越界:访问了数组中不存在的索引对应的元素,造成索引越界问题 。数组角标越界的异常:ArrayIndexOutOfBoundsExcetion
  • 空指针异常:访问的数组已经不再指向堆内存的数据,造成空指针异常。空指针异常:NullPointerException
  • null:空值,引用数据类型的默认值,表示不指向任何有效对象

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/3991199.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-10-21
下一篇 2022-10-21

发表评论

登录后才能评论

评论列表(0条)

保存