数组Java(详解)

数组:可以看成是相同类型元素的一个集合,在内存中是一段连续的空间。


一、什么是数组?

Java 语言中提供的数组是用来存储固定大小的同类型元素。
如:可以声明一个数组变量,如 numbers[100] 来代替直接声明 100 个独立变量 number0,number1,…,number99。
注意事项:

  1. 数组中存放的元素其类型相同
  2. 数组的空间是连在一起的
  3. 每个空间有自己的编号,其实位置的编号为0,即数组的下标。

二、数组的创建及初始化

数组的创建

T[ ] 数组名 = new T[N];
T:表示数组中存放元素的类型 如:int 、double
T[ ]:表示数组的类型 如:int[ ] 整型数组、double[ ] 浮点型数组
N:表示数组的长度 如:5表示存放5个对应类型的元素
如:

int[] arr1 = new int [10]; //创建一个可以容纳10个int类型元素的数组
char[] arr2 = new char[10]; //创建一个可以容纳10个char类型元素的数组
double[] arr4 = new double[10]; //创建一个可以容纳10个double类型元素的数组
String[] array3 = new String[10]; //创建一个可以容纳10个字符串的数组

数组的初始化

数组的初始化主要分为动态初始化以及**静态初始化 **

(1) 静态初始化:
静态初始化:在创建数组时不直接指定数据元素个数,而直接将具体的数据内容进行指定
如:

int[] arr1 = new int []{
    
    0,1,2,3,4,5,6,7,8,9};
char[] arr2 = new char[]{
    
    'a', 'b','c'};
double[] arr3 = new double[]{
    
    1.1,2.2,3.3,4.4,5.5};
String[] arr4 = new String[]{
    
    "abc","efg","hij"};

也可以将new T去掉,简写为:

int[] arr1 = {
    
    0,1,2,3,4,5,6,7,8,9};
char[] arr2 = {
    
    'a', 'b','c'};
double[] arr3 = {
    
    1.1,2.2,3.3,4.4,5.5};
String[] arr4 = {
    
    "abc","efg","hij"};

虽然省去了new T[ ], 但是编译器编译代码时还是会还原。
注意:

  1. 静态初始化虽然没有指定数组的长度,编译器在编译时会根据{}中元素个数来确定数组的长度。
  2. 静态初始化时, {}中数据类型必须与[]前数据类型一致。
  3. 静态初始化可以简写。

(2) 动态初始化
动态初始化:在创建数组时,直接指定数组中元素的个数
如:

int[] arr1 = new int [10]; //创建一个可以容纳10个int类型元素的数组
char[] arr2 = new char[10]; //创建一个可以容纳10个char类型元素的数组
double[] arr4 = new double[10]; //创建一个可以容纳10个double类型元素的数组
String[] array3 = new String[10]; //创建一个可以容纳10个字符串的数组

与静态初始化不同,动态初始化后续可以添加数组的内容,以int[ ] arr=new int [5]; 为例:

int[] arr = new int[5];
arr[0]=1;
arr[1]=2;
arr[2]=3;
arr[3]=4;
arr[4]=5;

静态和动态初始化也可以分为两步。

int[] array2;
array2 = new int[]{
    
    10, 20, 30}; //静态
int[] array1;
array1 = new int[10]; //动态

如果没有对数组进行初始化,数组中元素有其默认值:
image.png如果数组中存储元素类型为引用类型,默认值为null

三、数组中元素访问

数组的下标

数组在内存中是一段连续的空间,空间的编号都是从0开始的,依次递增,该编号称为数组的下标,数组可以通过下标访问其任意位置的元素。
image.png

遍历数组

length

数组的长度:数组名.length
在数组中可以通过 数组对象.length 来获取数组的长度,举例使用:‘

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

for each

语法:

for(元素类型t 元素变量x : 遍历对象obj){
    
     
     引用了x的java语句; 
} 

for-each 是for循环的另外一种使用方式,能够更方便的完成对数组的遍历. 可以避免循环条件和更新语句写错。
举例使用(打印数组内元素):

public class Test1 {
    
    
    public static void main(String[] args) {
    
    
        int[] arr = {
    
    1,2,3,4,5,6,7,8,9,10};
        for(int x:arr){
    
    
            System.out.println(x);
        }
    }
}

image.png

四、内存分布

内存是一段连续的存储空间,主要用来存储程序运行时数据的。 如果对内存中存储的数据不加区分的随意存储,那对内存管理起来将会非常麻烦,因此JVM(Java虚拟机)也对所使用的内存按照功能的不同进行了划分。
20191018124901149.jpeg
栈:一般存储局部变量等。 堆:一般存储对象等。
首先我们知道,Java中数据类型分为基本数据类型和引用数据类型,基本数据类型分为8种类型4大类,而引用数据类型中存放的是地址。

数组的内存分布

对于数组来说,其内存分布为:
image.png
那么问题来了,下面几道题打印arr2结果为什么?

int[] arr1 = {
    
    1,2,3,4,5};
int[] arr2 = arr1;

由上图可知,arr1中存放的是数组首元素的地址,将arr1赋给arr2,即arr2也指向{1,2,3,4,5},都与其建立了联系。打印arr2结果为1,2,3,4,5
image.png
如进行以下修改,打印arr2结果为什么?

int[] arr1 = {
    
    1,2,3,4,5};
int[] arr2 = arr1;
arr2[0] = 66;

因为arr2也与arr1所指向的内容建立了联系,因此不管谁进行修改,都会修改 {1,2,3,4,5},所以修改arr2[0]为66后,打印arr2结果为 66,2,3,4,5
若进行以下修改,打印arr1结果为什么?

int[] arr1 = {
    
    1,2,3,4,5};
int[] arr2 = {
    
    100,200,300};
arr1=arr2;

此时arr1中存放的地址是arr2所指向的元素的地址,与 {1,2,3,4,5} 的联系断开,因为没有人与 {1,2,3,4,5} 建立联系,所以其会被销毁。arr1打印结果为100,200,300

空 null

null 在 Java 中表示 “空引用” , 也就是一个不指向对象的引用

int[] arr = null; //arr数组不指向任何对象,以后若需要可以指向其它对象
System.out.println(arr[0]);//打印会报错

null 的作用类似于C语言中的 NULL (空指针), 都是表示一个无效的内存位置. 因此不能对这个内存进行任何读写操作. 一旦尝试读写, 就会报错 NullPointerException(空指针异常)。

五、数组的应用场景

保存数据

经常使用

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

作为函数的参数

public class Test {
    
    
    public static void main(String[] args) {
    
    
        int[] arr = {
    
    1, 2, 3};
        func(arr);
        System.out.println("arr[0] = " + arr[0]);//打印arr[0]=10
    }
    public static void func(int[] a) {
    
    
        a[0] = 10;
        System.out.println("a[0] = " + a[0]);//打印a[0]=10
    }
}

可以发现在func方法内部修改数组的内容, 方法外部的数组内容也发生改变. 因为数组是引用类型,按照引用类型来进行传递,是可以修改其中存放的内容的。

作为函数的返回值

public class Test1 {
    
    
    public static void main(String[] args) {
    
    
        int[] arr = func();//接收数组a所指向对象的地址
        System.out.println("arr[0] = " + arr[0]);
    }
    public static int[] func() {
    
    
        int[] a= {
    
    1,2,3,4,5,6,7,8,9,10};
        System.out.println("a[0] = " + a[0]);
        return a;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_74837727/article/details/130232906