【JavaSE】数组

文章目录

  • 数组概念
  • 数组的创建和初始化
    • 数组的创建
    • 数组的定义
  • 数组的使用
    • 数组中元素访问
    • 遍历数组
    • 数组拷贝
  • 引用类型->数组
    • 初始JVM内存布局
    • 基本类型变量与引用类型变量的区别
    • null
  • 二维数组
    • 基本语法
    • 二维数组的创建
    • 二维数组的访问
    • 不规则数组

数组概念

概念: 数组是相同类型元素的集合

内存布局: 在内存中是一段连续的空间。

注:

  1. 数组中存放的元素类型是相同的
  2. 在空间上是连续存放的
  3. 每个空间都有对应的编号,起始位置下标为0。

数组的创建和初始化

数组的创建

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

T:数组元素类型
N: 元素个数

数组的定义

数组的定义有2种方式

1.动态初始化:在创建数组时,直接指定数组元素的个数

int[] arr = new int[10]
  1. 静态初始化:在创建数组的同时初始化其数据

语法格式:T[ ] arr = {data1, data2 …};

int[] arr1 = new int[]{0,1,2,3,4,5,6,7,8,9};
double[] arr2 = new double[]{1.0, 2.0, 3.0, 4.0, 5.0};
String[] arr3 = new String[]{"hello", "Java", "!!!"};

注:

  • 静态初始化虽然没有指定数组的长度,编译器在编译时会根据{}中元素个数来确定数组的长度。
  • 静态初始化时, {}中数据类型必须与[]前数据类型一致。
  • 静态初始化可以简写,省去后面的new T[]。
// 注意:虽然省去了new T[], 但是编译器编译代码时还是会还原
int[] array1 = {0,1,2,3,4,5,6,7,8,9};
double[] array2 = {1.0, 2.0, 3.0, 4.0, 5.0};
String[] array3 = {"hello", "Java", "!!!"};
  • 静态和动态初始化也可以分为两步,但是省略格式不可以
        int[] arr;
        arr = new int[]{1,2,3};

        int[] arr1;
        arr1 = new int[13];
        //error
        int[] arr2;
        arr2 = {1,2,3};
  • 如果没有对数组初始化,那么数组其默认值根据数组类型来初始化(引用类型默认为null)
类型 默认值
byte 0
short 0
int 0
long 0
float 0.0f
double 0.0
char /u0000
boolean false

数组的使用

数组中元素访问

数组在内存中是一段连续的空间,空间的编号都是从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为元素个数,不能越界,否则会报出下标越界异常。

遍历数组

遍历: 是指将数组中的所有元素都访问一遍, 访问是指对数组中的元素进行某种操作,比如:打印

打印有三种方法:

  1. 知道数组元素个数,利用循环打印
        int arr[] = new int[]{1,2,3,4,5,6};
        for (int i = 0; i < 6 ; i++) {
            System.out.print(arr[i] + " ");
        }
  1. 利用数组对象.length 直接获取数组长度
        int arr[] = new int[]{1,2,3,4,5,6};
        for (int i = 0; i < arr.length ; i++) {
            System.out.print(arr[i] + " ");
        }
  1. 使用for - each遍历数组
    Java有一种功能很强的循环结构,可以用来依次处理数组中的每个元素(其他类型的元素集合亦可)而不必为指定下标值而分心。

语句格式:for (variable : collection) statement
collection这一集合表达式必须是一个数组或者是一个实现了Iterable接口的类对象(例如ArrayList).variable代表的是每个元素类型

        int arr[] = new int[]{1,2,3,4,5,6};
        for (int x : arr){
            System.out.print(x + " ");
        }

这个循环叫做循环arr中的每一个元素,可以使语句更加简洁,更不容易出错(我们不必关系下标值和终止条件)

  1. 利用 Arrays类的toString方法
    public static void main(String[] args) {
        int[] arr = new int[] {1,2,3,4};
        System.out.println(Arrays.toString(arr));
    }

在这里插入图片描述

数组拷贝

  1. 在Java中,允许将一个数组变量拷贝给另一个数组变量。这时,两个变量将引用同一个数组:
        int[] arr1 = new int[] {1, 2, 3, 4};
        int[] arr2 = arr1;

注:由于arr1和arr2都指向同一对象,所以修改二者中任意一个元素,另一个也会改变。

  1. 如果我们希望把一个数组中所有元素拷贝到一个新数组中,这时候我们就需要使用Arrays类的copyof方法;
    public static void main(String[] args) {
        int[] arr1 = new int[] {1, 3, 5, 7, 9};
        int[] arr2 = Arrays.copyOf(arr1,arr1.length);
    }

第2个参数是新数组的长度。这个方法通常用来增加数组的大小:int[] arr2 = Arrays.copyof(arr1,arr.length * 2);如果数组元素是数值型,那么多余的元素将被赋值为0;如果数组元素是布尔型,则将赋值为false。相反,如果长度小于原始数组的长度,则只拷贝最前面的数据元素。

  1. 使用System.arraycopy(Object src, int srcPos,Object dest, int destPos,int length);

这个copy十分强大,可以copy任何类型的数据。

    public static void main(String[] args) {
        int[] arr = {1,2,3,4};
        /**
         * public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
         * src - 源数组。
         * srcPos - 源数组中的起始位置。
         * dest - 目标数组。
         * destPos - 目的地数据中的起始位置。
         * length - 要复制的数组元素的数量。
         */
        int[] arr1 = new int[10];
        System.arraycopy(arr,0,arr1,1,arr.length - 1);
        System.out.println(Arrays.toString(arr1));//[0, 1, 2, 3, 0, 0, 0, 0, 0, 0]
    }

引用类型->数组

初始JVM内存布局

内存是一段连续的存储空间,主要用来存储程序运行时数据的

在程序运行时代码,数据,常量等需要加载到内存中,一些方法运行结束时需要销毁,如果我们不对数据加以区分管理,那么对内存管理将会十分麻烦,所以在JVM中,按照不同的功能对内存进行划分:

【JavaSE】数组_第1张图片

  • 程序计数器 (PC Register): 只是一个很小的空间, 保存下一条执行的指令的地址
  • 虚拟机栈( JVM Stack): 与方法调用相关的一些信息,每个方法在执行时,都会先创建一个栈帧 ,栈帧中包含有:局部变量表、操作数栈、动态链接、返回地址以及其他的一些信息,保存的都是与方法执行时相关的一些信息。比如:局部变量。当方法运行结束后,栈帧就被销毁了,即栈帧中保存的数据也被销毁了。
  • 本地方法栈(Native Method Stack): 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的
  • 堆( Heap): JVM所管理的最大内存区域. 使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2,
    3} ),堆是随着程序开始运行时而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销毁。
  • 方法区(Method Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据. 方法编译出的的字节码就是保存在这个区域

基本类型变量与引用类型变量的区别

基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的是其所对应的值;
而引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址。
public static void func() {
int a = 10;
int b = 20;
int[] arr = new int[]{1,2,3};
}

【JavaSE】数组_第2张图片
注:引用变量并不直接存储对象本身,可以简单理解成存储的是对象在堆中空间的起始地址。通过该地址,引用变量便可以去操作对象

null

null 在 Java 中表示 "空引用" , 也就是一个不指向对象的引用
int[] arr = null;
System.out.println(arr[0]);
// 执行结果
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:6)

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

注意: Java 中并没有约定 null 和 0 号地址的内存有任何关联

二维数组

二维数组本质上是一个一维数组,不同于C,Java中二维数组在空间上不是连续的。

基本语法

数据类型[][] 数组名称 = new [行数][列数] {初始化数据}

二维数组的创建

同一维数组,二维数组也有两种创建方式:

  • 动态初始化
	int[][] array = {{1,2,3},{4,5,6}};
    int[][] array2 = new int[][]{{1,2,3},{4,5,6}};
  • 静态初始化
	int[][] array3 = new int[2][3];

二维数组的访问

  • 普通打印
        int[][] array = {{1,2,3},{4,5,6}};
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j] +" ");
            }
            System.out.println();
        }

在这里二维数组中其实存放的两个一维数组的地址;所以通过array[i].length就可以得到一维数组的长度,这就衍生出了不规则数组

  • 利用for-each打印

我们知道for-each中的两个参数一个是存放集合元素的变量,另一个是这个集合;我们知道这个集合是array,但存放元素变量不是int类型,而是int [ ],但是这样访问得到的是两个一维数组,现在就同一维数组一样打印。

 int[][] array = {{1,2,3},{4,5,6}};
 for(int[] tmp : array) {
            for(int x : tmp) {
                System.out.print(x+" ");
            }
            System.out.println();
        }

不规则数组

int[][] array2 = new int[2][];

        array2[0] = new int[2];
        array2[1] = new int[4];

        for (int i = 0; i < array2.length; i++) {
            for (int j = 0; j < array2[i].length; j++) {
                System.out.print(array2[i][j] +" ");
            }
            System.out.println();
        }

不规则数组标题与我们在C中的二维数组,我们可以先定义我们需要几个一维数组,然后为其赋予空间。

你可能感兴趣的:(JavaSE,java,排序算法,算法)