java数组详解

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

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

数组的创建及初始化

T[] 数组名 = new T[N];

T:表示数组中存放元素的类型
T[]:表示数组的类型
N:表示数组的长度

常见的java数组定义有三种方式

//数组
public class helloworld{
    public static void main(String[] args) {
        //java定义数组的第一种方式
        int[] arr1 = {1,2,3,4,5,6};
        //java定义数组的第二种方式
        int[] arr2 = new int[]{1,2,3,4,5,6};
        //java定义数组的第三种方式
        int[] arr3 = new int[10];//d动态初始化
    }
}
int[] arr1 = {1,2,3,4,5,6};

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

他们都是静态初始化,都是在内存中开辟了六个整型变量的存储空间(连续),并且初始为123456

new是一个java的关键字,一般通过new来实现实例化对象。java中的数组其实就是一个对象。

最后一种只是开辟了一块内存空间(10个整型变量)又名动态初始化。系统默认数组元素没有初始化之前的值为0。

 //java定义数组的非法定义
        int[] arr4 = new int[10]{1,2,3,4}//非法定义

java中 后面的[]中的数字与初始化的123456等是不能同时存在的,两者只能存在一个。

初始化也可以分成两步
此外一开始不初始化,后面初始化也可以

	   int[] arr5 ;
 		arr5 = new int[]{1,2,3 4};//静态初始化分成两步
 		int[] arr6;
 		arr6 = new int[10];//动态初始化分成两步

分成两步是注意,数组类型是不可以省略的。
所以这样是非法的

       int[] arr6;
       arr6 = {1,2,3,4,5}//非法初始化
       int[] arr7 = new int[10];
       arr = {1,2,3,4,5,6,7,8,9,10}//非法初始化

前面说了,int型数组没有手动初始化,系统会默认初始化为0.此外、其他数据类型也会系统也会初始化成特定的类型。

在这里插入图片描述如果数组中存储类型是引用类型,默认值为NULL;

实际上之所以数组和其他数据类型不一样,创建时需要用到new 而像int char等都不需要用到,这是因为数组是引用类型,其实字符串类型也是引用类型,但是字符串创建的时候可以直接写 String str = “abcde”,其实这是简写,真正的书写是String str =new String “abcde”.

数组的使用

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

int[]array = new int[]{10, 20, 30, 40, 50};
System.out.println(array[0]);
System.out.println(array[1]);
System.out.println(array[2]);
System.out.println(array[3]);
System.out.println(array[4]);
// 也可以通过[]对数组中的元素进行修改
array[0] = 100;
System.out.println(array[0]);
  1. 数组是一段连续的内存空间,因此支持随机访问,即通过下标访问快速访问数组中任意位置的元素
  2. 下标从0开始,介于[0, N)之间不包含N,N为元素个数,不能越界,否则会报出下标越界异常
    在这里插入图片描述在数组中可以通过 数组对象.length 来获取数组的长度
public class helloworld{
    public static void main(String[] args) {
        int[] arr1 = new int[4];
        System.out.println(arr1.length);
    }
}

在这里插入图片描述遍历数组

可以使用for循环

int[]array = new int[]{10, 20, 30, 40, 50};
for(int i = 0; i < 5; i++){
	System.out.println(array[i]);
}

也可以使用for-each

public class helloworld{
    public static void main(String[] args) {
        int[] arr1 = new int[4];
        System.out.println(arr1.length);
        for(int x:arr1){//元素类型 x : 数组名
            System.out.println(x);//x也可以改成y、z等
        }
    }
}

此外,还可以导入java里面的array包,调用这个包里面的方法
如果单纯只是打印数组里面的内容,可以使用toString方法
在这里插入图片描述

import java.util.Arrays;//java类里面的Arrays
public class helloworld {
    public static void main(String[] args) {
        int[] arr1 = new int[4];
        System.out.println(arr1.length);
//        for (int x : arr1) {
//            System.out.println(x);//x也可以改成y、z等
        System.out.println(Arrays.toString(arr1));
    }
}

在这里插入图片描述

数组是引用类型

java代码是运行在jvm虚拟机中,虚拟机中也是要对内存你进行划分的,可以划分成:本地方法栈、堆、程序计数器、方法栈、虚拟机栈
我们平时说栈实际是虚拟机栈。
从底层来时,系统运行int[] array = new int[] {1,2,3,4}这段代码的时候,会先堆区创建四个整型变量(16个字节)的连续空间用来存1234,然后在栈区(虚拟机栈)中创建一个array变量,并存上 1234的首地址,所以其实这玩意和C里面的指针很像。所以这个引用类型应该也是四个字节
在这里插入图片描述

public class helloworld {
    public static void main(String[] args) {
        int[] arr1 = new int[]{1,2,3,4};
        System.out.println(arr1);
     }
}

在这里插入图片描述
如果将引用变量赋值为null,那么就是说这个arr1指向空

import java.util.Arrays;//java类里面的Arrays
public class helloworld {
    public static void main(String[] args) {
        int[] arr1 ;
        arr1 = null;
        System.out.println(arr1);//打印出来是null
        System.out.println(arr1[0]);//报错
    }
}

在这里插入图片描述注意的是
C语言NULL可能指向的是0号地址空间,这个地址空间是受保护的,是不可以被访问的,所以会报错,但是java里面null没有和0号地址关联。
JAVA中NULL只表示不指向任何对象。

数组传参
//SE.7.01:00:00

先来看这个代码

import java.util.Arrays;

public class helloworld {
    public static void fun_1(int[] arr) {
        arr = new int[]{10, 11, 12};
        System.out.println(Arrays.toString(arr));//结果是【10,11,12】
    }

    public static void fun_2(int[] arr) {
        arr[0] = 188;
    }

    public static void main(String[] args) {
        int[] arr1 = new int[]{1, 2, 3, 4, 5};
        int[] arr2 = new int[]{6, 7, 8, 9, 10};
        fun_1(arr1);
        fun_2(arr2);
        System.out.println(Arrays.toString(arr1));//结果依旧是盘【1,2,3,4,5】
        System.out.println(Arrays.toString(arr2));//结果是【188,7,8,9,10】
    }
}

我们把整个过程顺一遍,首先在系统的堆区开辟两片连续内存空间,一片存1,2,3,4,5,一片存6,7,8,9,10。因为是在main函数内,所以arr1和arr2都是局部变量。所以是在栈区创建两个指向整型数组的引用类型变量arr1,arr2分别指向前面两块空间的首地址。假设arr1存的是0x12345678
arr2存的是0x45678912
现在执行fun1,arr还是局部变量,所以还是创建在栈区,然后将arr1的内容传给arr,所以arr的内容是0x12345678,然后执行new int[]{10, 11, 12};
这一句,系统在堆区开辟一块空间存的是10,11,12,假设首地址是0x24681012,然后将arr指向这片空间,此时就要注意了,这之后,arr的内容不再是0x12345678,而是新的0x24681012.所以后面打印时,打印的是10,11,12.然后fun1执行结束,栈区里面的arr出栈,也就是局部变量销毁,同时堆区里面的0x12345678这片空间释放。
但是执行fun_2时,因为堆区并没有开辟新的空间,所以arr还是存的是0x45678912,所以arr[0]赋值188就是原本0x45678912这里的第一个元素改为188,所以打印时的元素会是188,7,8,9,10

所以实际上,当数组作为参数传递时,还是按值去传递的
当形参修改指向时: arr = new int[]{10, 11, 12};只会影响形参指向,对实参没有任何影响
当形参修改指向对象的值时,实参才会受到影响arr[0] = 188;

数组作为返回值
SE.07.01:31:37

import java.util.Arrays;

public class helloworld {
    public static int[] fun_double(int[] arr) {
        int i = 0;
        for (i = 0; i < arr.length; i++) {
            arr[i] = arr[i] * 2;
        }
        return arr;
    }

    public static void main(String[] args) {
        int[] arr1 = new int[]{1, 2, 3, 4, 5};
        int[] ret = fun_double(arr1);
        System.out.println(Arrays.toString(ret));
    }
}

在这里插入图片描述

但是下面这个代码要注意

import java.util.Arrays;

public class helloworld {
    public static int[] fun_double(int[] arr) {
        int i = 0;
        for (i = 0; i < arr.length; i++) {
            arr[i] = arr[i] * 2;//这里对实参也有影响
        }
        return arr;
    }

    public static void main(String[] args) {
        int[] arr1 = new int[]{1, 2, 3, 4, 5};
        int[] ret = fun_double(arr1);
        System.out.println(Arrays.toString(ret));//打印出来是[2, 4, 6, 8, 10]
        System.out.println(Arrays.toString(arr1));//打印出来也是[2, 4, 6, 8, 10]
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值