折叠

Java全栈第四篇-数组

第一章 数组的定义和范围

 

1.1、产生背景:

     在通常的统计或者分析过程中,我们需要定义同种类型的多个变量,重复的定义过于麻烦,所以我们需要一个容器将一连串同种类型的数据装进去,调用时只需要调用一种容器即可,而这种容器即为数组。

 

1.2、概念:

     数组就是存储数据长度固定的容器,保证多个数据的数据类型要一致。

 

1.3、特点:

(1)、数组是一种引用数据类型。

(2)、数组当中的多个数据,类型必须统一。

(3)、数组的长度在程序运行期间不可改变。

 

1.4、定义格式:

(1)、动态初始化(指定长度)

数组储存的数据类型[] 数组名字 = new 数组储存的数据类型[长度];

(2)、静态初始化(指定内容)

//标准格式
数据类型[] 数组名称 = new 数据类型[] { 元素1, 元素2, ... };
//省略格式
数据类型[] 数组名称 = { 元素1, 元素2, ... };

名词或符号的释义:

(1)数组储存的数据类型:创建的数组容器可以存储什么数据类型。(所有元素统一)

(2)[ ] :表示数组。

(3)数组名字:为定义的数组起个变量名,满足标识符规范,可以使用名字操作数组。

(4)new :关键字,创建数组使用的关键字。

(5)长度:数组的长度,表示数据容器中可以存储多少个元素。

使用建议:如果不确定数组当中的具体内容,用动态初始化;已经确定了具体内容,用静态初始化。

注意事项:(1)静态初始化没有直接告诉数组的长度,可以根据元素的个数推断出数组长度。

                  (2)动态初始化数组有定长特性,长度一旦指定,不可更改。

实例:

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

        // 静态初始化的标准格式.
        int[] arrayB= new int[] { 11, 21, 31 };
      
        // 动态初始化的标准格式
        int[] arrayC= new int[5];

        // 注意事项:静态初始化和动态初始化的标准格式可以拆分成两个步骤
        //         静态初始化的省略格式,不能拆分成为两个步骤。

    }
}

 

1.5、数组的访问

(1)索引:每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,到(length-1)结束,这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。

(2)访问格式:

数组名[索引]

(3)数组的长度:每个数组都具有长度,采用语句:数组名.length 可以得到数组的长度,得到的数组长度必然是一个int类型数值。

实例:

public class BlogTest {
    public static void main(String[] args) {
        int [] arr = {10,20,30};
        //打印数组的长度,输出结果为3
        System.out.println(arr.length);
    }
}

(4)动态初始化数组时,元素被自动赋予默认值的规则:

         整数类型,默认为0                浮点类型,默认为0.0

         字符类型,默认为‘\u000’        布尔类型,默认为false

         引用类型,默认为null

注意事项:

               (1)索引值从0开始,一直到"数组长度-1"结束。

               (2)直接打印数组的名称,直接得到的是数组的内存地址哈希值。

               (3)静态初始化其实也有默认值的过程,只不过系统自动马上将默认值替换成具体数值。

实例:

public class BlogTest {
    public static void main(String[] args) {
        //静态初始化一个数组
        int [] arr ={10,20,30,40,60};
        //动态初始化创建一个数组
        int [] arr1 = new int[8];
        //从静态数组中利用索引值打印数据
        System.out.println(arr[0]);
        //得到两种数组的地址哈希值
        System.out.println(arr);
        System.out.println(arr1);
        //从动态数组中利用索引值打印默认数据
        System.out.println(arr1[0]);
    }
}

运行结果:

 

第二章  数组原理内存图

 

2.1 内存概述

      内存是计算机中的重要原件,临时存储区域,作用是运行程序。我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存。

      Java虚拟机需要运行程序,必须要对内存进行空间的分配和管理。

 

2.2 Java虚拟机的内存划分

(1)方法栈(stack):存放的都是方法中的局部变量。方法的运行一定要在栈当中运行。

         拓展:局部变量:方法的参数,或者是方法语句体中的变量。

                    作用域:一旦超出作用域,立刻从栈内存当中消失。

(2)堆内存(Heap):存储对象或者数组,凡是new创建的对象或者数组,都在堆中。

         拓展:堆内存里面的东西都有一个地址值:16进制

                    堆内存里面的数据,都有默认值,规则和数组动态初始化默认值的规则相同。

(3)方法区(Area):存储.class相关信息,包含方法的信息。

(4)本地方法栈(Native Method Stack):与操作系统相关。

(5)寄存器(pc Register):与CPU相关。

 

2.3 数组在内存中的存储

(1)一个数组内存图

        源程序

public class Demo01ArrayOne {

    public static void main(String[] args) {
        int[] array = new int[3]; // 动态初始化
        System.out.println(array); // 地址值
        System.out.println(array[0]); // 0
        System.out.println(array[1]); // 0
        System.out.println(array[2]); // 0
        System.out.println("==============");

        // 改变数组当中元素的内容
        array[1] = 10;
        array[2] = 20;
        System.out.println(array); // 地址值
        System.out.println(array[0]); // 0
        System.out.println(array[1]); // 10
        System.out.println(array[2]); // 20
    }
}

          内存中的体现

          解释:(1)首先.class程序入口进入方法曲(public static void main(String [ ] args))

                     (2)main方法优先进入方法方法栈中执行

                     (3)在main中创建新数组(new),JVM会在堆内存中开辟空间,存储数组

                     (4)数组在堆内存当中得到了自己的内存地址,以十六进制数表示。

                     (5)数组中的三个元素在没有赋值之前默认值均为0

                     (6)JVM将数组的内存地址赋给引用类型变量arr(new的那部分还在堆内存中)

                     (7)无论是在调用arr进行元素赋值还是更改原来元素值时,都是利用arr中储存的地址值去堆内存中找到数组并对元素值进行修改。

(2)两个数组内存图

          源程序

public class Demo02ArrayTwo {

    public static void main(String[] args) {
        int[] arrayA = new int[3];
        System.out.println(arrayA); // 地址值
        System.out.println(arrayA[0]); // 0
        System.out.println(arrayA[1]); // 0
        System.out.println(arrayA[2]); // 0
        System.out.println("==============");

        arrayA[1] = 10;
        arrayA[2] = 20;
        System.out.println(arrayA); // 地址值
        System.out.println(arrayA[0]); // 0
        System.out.println(arrayA[1]); // 10
        System.out.println(arrayA[2]); // 20
        System.out.println("==============");

        int[] arrayB = new int[3];
        System.out.println(arrayB); // 地址值
        System.out.println(arrayB[0]); // 0
        System.out.println(arrayB[1]); // 0
        System.out.println(arrayB[2]); // 0
        System.out.println("==============");

        arrayB[1] = 100;
        arrayB[2] = 200;
        System.out.println(arrayB); // 地址值
        System.out.println(arrayB[0]); // 0
        System.out.println(arrayB[1]); // 100
        System.out.println(arrayB[2]); // 200
    }

}

         内存中的体现

          解释:分开采用一个数组的内存图组合而成,两者并没有联系。

(3)两个引用指向同一个数组的内存图

         源程序

public class Demo03ArraySame {

    public static void main(String[] args) {
        int[] arrayA = new int[3];
        System.out.println(arrayA); // 地址值
        System.out.println(arrayA[0]); // 0
        System.out.println(arrayA[1]); // 0
        System.out.println(arrayA[2]); // 0
        System.out.println("==============");

        arrayA[1] = 10;
        arrayA[2] = 20;
        System.out.println(arrayA); // 地址值
        System.out.println(arrayA[0]); // 0
        System.out.println(arrayA[1]); // 10
        System.out.println(arrayA[2]); // 20
        System.out.println("==============");

        // 将arrayA数组的地址值,赋值给arrayB数组
        int[] arrayB = arrayA;
        System.out.println(arrayB); // 地址值
        System.out.println(arrayB[0]); // 0
        System.out.println(arrayB[1]); // 10
        System.out.println(arrayB[2]); // 20
        System.out.println("==============");

        arrayB[1] = 100;
        arrayB[2] = 200;
        System.out.println(arrayB); // 地址值
        System.out.println(arrayB[0]); // 0
        System.out.println(arrayB[1]); // 100
        System.out.println(arrayB[2]); // 200
    }

}

         在内存中的表现

         解释:把第一个数组的名称直接赋给第二个数组,实际上是将第一个数组的地址赋予了第二个数组。第二个数组与第一个数组的地址相同,在堆内存中使用相同数组 。第二个数组通过第一个数组的地址对                      第一个数组内元素的数值进行修改。

 

第三章   数组的常见操作

 

3.1 数组越界异常

(1)规范:数组的索引编号从0开始,一直到"数组的长度-1"为止

(2)异常:访问数组是所采用的索引编号不存在,就会发生数组所以越界异常

实例:

public class BlogTest {
    public static void main(String[] args) {
        //静态初始化一个数组
        int [] arr ={10,20,30,40,60};
        //访问数组中不存在的元素
        System.out.println(arr[8]);
    }
}

运行结果:

 

3.2 数组空指针异常

(1)了解:所有的引用类型变量,都可以赋值为一个null值,但是代表其中什么都没有。

(2)数组规范:数组必须进行new的初始化才能使用其中的元素。

                           如果数组仅仅只被赋值了一个null,没有进行new创建,那么就会产生空指针异常。

实例:

public class BlogTest {
    public static void main(String[] args) {
        //静态初始化一个数组
        int [] arr ={10,20,30,40,60};
        //访问被赋值为null的数组中的元素,不经过new的创建。
        int [] arr1 = null;
        System.out.println(arr[1]);
        System.out.println(arr1[1]);
    }
}

运行结果:

 

3.3 数组的遍历

(1)定义:就是将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基石。

(2)方法:利用for循环语句循环打印出数组中的每一个元素。

实例:

 public static void main(String[] args) {
    int[] arr = { 1, 2, 3, 4, 5 };
    for (int i = 0; i < arr.length; i++) {
      System.out.println(arr[i]);
    }
}

运行结果:

 

3.4 获取数组中的最大元素

(1)实现思路:定义变量(存储第0号元素)—遍历数组—将其它元素与定义的变量进行比较,较大者替换较小者。

实例:

public class BlogTest {
    public static void main(String[] args) {
        int[] arr = { 105, 34, 85, 1111, 164, 542 };
        //定义变量,保存数组中0索引的元素
        int max = arr[0];
        //遍历数组,取出每个元素
        for (int i = 1; i < arr.length; i++) {
            //遍历到的元素和变量max比较
            //如果数组元素大于max
            if (arr[i] > max) {
                //max记录住大值
                max = arr[i];
            }
        }
        System.out.println("数组最大值是: " + max);
    }
}

运行结果:

 

3.5 数组的反转

(1)定义:数组中的元素颠倒顺序,例如原始数组为1,2,3,4,5,反转后的数组为5,4,3,2,1

(2)实现思路:将数组两端的元素交换—需要两个变量来储存最大索引和最小索引—将两个索引的元素进行交换—最大索引递减,最小索引递增,重复操作—最小索引超过最大索引,反转结束。

实例:

public class BlogTest {
    public static void main(String[] args) {
        int[] array = { 15, 25, 35, 45, 55 };

        // 遍历打印数组本来的样子
        System.out.print("反转前:");
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+" ");
        }
        //数组反转
        for (int min = 0, max = array.length - 1; min < max; min++, max--) {
            int temp = array[min];
            array[min] = array[max];
            array[max] = temp;
        }

        // 再次打印遍历输出数组后来的样子
        System.out.print("反转后:");
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+" ");
        }
    }

}

运行结果:

 

第四章 数组作为方法参数或返回值

 

4.1 数组作为方法参数

(1)注意事项:当调用方法的时候,向方法的小括号进行传参,传递进去的其实是数组的地址值。

实例:

public class BlogTest {

    public static void main(String[] args) {
        int[] array = { 15, 25, 35, 45, 55 };
        System.out.println(array); // 地址值
        printArray(array); // 传递进去的就是array当中保存的地址值
    }
    //创建打印数组的方法printArray
    public static void printArray(int[] array) { //利用数组作为参数
        System.out.println("printArray方法收到的参数是:");
        System.out.println(array); // 地址值
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }
}

运行结果:

 

4.2 数组作为方法返回值

(1)了解:任何数据类型都能作为方法的参数类型,或者返回值类型。

(2)数组作为方法返回值的背景:如果希望一个方法返回多个结果数据,则需使用一个数组作为返回值类型。

(3)注意事项:(1)数组作为返回值,返回值类型则对应数组的引用类型。

                           (2)数组作为方法的返回值,返回的也是数组的地址值。

实例:

public class BlogTest {

        public static void main(String[] args) {
            //在main方法中创建一个数组接收calculate方法返回的数组
            int[] result = calculate(10, 20, 30);

            System.out.println("main方法接收到的返回值数组是:");
            System.out.println(result); // 地址值

            System.out.println("总和:" + result[0]);
            System.out.println("平均数:" + result[1]);
        }

        public static int[] calculate(int a, int b, int c) {
            int sum = a + b + c; // 求和
            int avg = sum / 3; // 求平均数

            int[] array = {sum, avg};
            System.out.println("calculate方法内部数组是:");
            System.out.println(array); // 地址值
            return array;//地址值
        }

}

运行结果:

                      

 

posted @ 2020-05-07 14:12  Coverpast  阅读(206)  评论(0编辑  收藏  举报