数组

一、数组的定义与访问

1. 数组的概念

数组是一种容器,可以同时存放多个数据值

2. 数组的特点:

  • 数组是一种引用类型

  • 数组当中的多个数据类型是统一的

  • 数组的长度在程序运行期间不会发生改变

  • 数组的初始化:在内存当中创建一个数组,并赋予默认值。

2.1两种常见的初始化方式:

  • 动态初始化(指定长度),在创建的时候直接指定数据元素个数

    • 动态初始化数组的基本格式:

    • 数据类型[] 数组名称 = new 数据类型[数组长度];
      /*
      *左侧数据类型:表示数组当中保存的数据,其类型是统一的
      *左侧中括号:代表是一个数组
      *右侧new:代表创建数组的动作
      *右侧数据类型:和左边的数据类型一致
      *右侧中括号的数组长度:表示在数组中可以存储的数据量,是一个int
      */
      
    • 使用动态初始化数组时,元素自动有一个默认值

      • 整数类型默认为0;
      • 浮点类型默认为0.0;
      • 字符类型默认为'\u000';
      • boolean类型默认为false;
      • 引用类型默认为null
  • 静态初始化(指定内容),不直接指定数据个数,而是指定具体的数据内容

    • 静态初始化数组的基本格式:数据类型[] 数组名称 = new 数据类型[]{元素1,元素2,...}
    • 静态初始化数组的省略格式:数据类型[] 数组名称 = {元素1,元素2,...}
    • 注意事项
      • 虽然静态初始化没有直接告诉长度,但根据大括号里的内容,可以推算出长度
      • 静态初始化的标准格式可以拆分为两个步骤数据类型[] 数组名称;数组名称 = new 数据类型[数组长度];
      • 动态初始化的标准格式也可以拆分为两个步骤
      • 静态初始化如果使用了省略格式,就不能拆分为两个步骤
  • 如果不确定数组当中的具体内容,用动态初始化,反之用静态初始化

3. 数组的访问

  • 索引: 每一个存储到数组的元素,都会自动的拥有一个编号,从0开始到数组长度-1,这个自动编号称为数组的索引(index),可以通过数组的索引访问到数组中的元素。若是直接打印数组名称,只会得到数组对应的内存地址哈希值
  • 访问数组的格式:数组名称[索引值]

二、数组原理内存图

1. 内存简介

内存是数据的临时存储区域。我们编写的程序是存放在硬盘中的,但不会运行,只有放进内存中才能运行,运行完毕后会清空内存。Java虚拟机要运行程序,就要对内存进行空间的管理和分配。

2. Java虚拟机的内存划分

为了提高运算效率,可以将空间划分为不同区域的,每一片区域有特定的处理数据方式和内存管理方式。

  • JVM的内存划分:
    • 栈(Stack):存放方法中的局部变量。方法的运行一定是在栈中
      • 局部变量:方法的参数,也就是方法{}内部的变量
    • 堆(Heap)凡是new出来的,都在堆中。堆里面的数据都有一个16进制的地址值
    • 方法区(Method Area):存储.class相关信息,包含方法的信息。
    • 本地方法栈(Native Method Stack):和操作系统相关
    • 寄存器(pc Register):和CPU相关

3. 数组在内存中的存储

  • 一个数组的内存图,对下面代码进行分析:
public class ArrayOne {
    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
    }
 
}

  • 两个数组内存图,对如下代码进行分析:
public class ArrayTwo {
    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
    }
}

  • 两个变量指向一个数组:
public class ArraySame {
 
    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
    }
 
}


三、数组的常见操作

1. 数组越界异常

  • 程序出现异常:ArrayIndexOutOfBoundsException
  • 出现原因:索引编号写错,访问数组元素时,索引编号不存在。
  • 解决方法:修改成为正确的索引编号

2. 空指针异常

  • 程序出现异常:NullPointerException
  • 出现原因:数组没有进行new初始化就直接使用其中的元素。若数组只赋值了一个null,没有进行new的创建,则会发生空指针异常
  • 解决方法:补上new

3. 获取数组长度

  • 格式:数组名。length
  • 再次强调:数组创建后,程序运行期间长度可改变

4. 数组的遍历

  • 遍历数组:对数组中的每一个元素逐一处理,通常默认打印输出
  • 处理用原始方式一一打印外,还可用for循环
/*快捷方式:数组名称.fori*/
	for(int i = 0;i < 数组名.length;i++){
        
    }

5. 练习

求出数组中的最值

  • 一般的思路:
    • 设置一个变量,将最大值保存在变量max中
    • 把其他的数与变量的值进行比较,若该数大于max,就把更大的数值赋给变量max
    • 重复比较,直到变量max的值为最大
int a = 10,b = 20,c = 30;
int max = a;
if(b > max){
    max = b;
}
if(c > max){
    max = c;
}
System.out.println(max);
  • 若在数组中比较,就需要用到遍历
int array = {10,20,30,40,50}
int max = array[0];
for (int i = 1;i < array.length;i++){
    if (array[1] > max){
        max = array[i];
    }
    System.out.println("最大值是"+max);
}

数据元素反转

在不使用新数组的情况下,使用原数组完成

  • 思路:数组反转就是对称位置的交换,我们用两个索引表示对称位置,再通过第三个变量让两者交换,当min==max或min>max时停止
  • 程序如下:
for (int min = 0,max = array.length - 1;min < max;min++,max--){
	int temp = array[min];
	array[min] = array[max];
	array[max] = temp;
}

四、数组作为方法参数和返回值

1. 数组作为方法参数

  • 当调用方法时,向方法的小括号进行传参,传递进去的是数组的地址值
public static void main(String[] args) {
int[] arr = { 1, 3, 5, 7, 9 };
//调用方法,传递数组
    printArray(arr);
} 
/*
创建方法,方法接收数组类型的参数
进行数组的遍历
*/
public static void printArray(int[] arr) {
    for (int i = 0; i < arr.length; i++) {
        System.out.println(arr[i]);
        }
    }

2. 数组作为方法返回值

  • 数组作为方法的返回值,返回的是数组的内存地址
  • 一个方法可以有多个参数,但只能有0或1个返回值,不能出现多个返回值。此时可以用数组解决
posted @ 2020-05-14 23:35  弥漫s  阅读(133)  评论(0)    收藏  举报