专业的JAVA编程教程与资源

网站首页 > java教程 正文

为什么要使用数组?如何使用数组?(什么是数组为什么要使用数组)

temp10 2024-11-16 00:41:17 java教程 15 ℃ 0 评论

为什么要使用数组?
1.可以解决大量数据的命名问题。
2.可以解决大量数据的存储和传递问题
数组是编程语言中常见的一种数据结构,可用于存储多个数据,每个数组元素存储一个数据,通常可通过数组元素的索引来访问数组元素,包括为数组元素赋值和取出数组元素的值。

Java的数组要求所有的数组元素具有相同的数据类型。
注意:因为Java是面向对象的语言,然而类与类之间是可以继承的,所以会形成一个数组里面含有多种数据类型的假象。

为什么要使用数组?如何使用数组?(什么是数组为什么要使用数组)

例如:
数 组 为 水果类
数组元素 苹果类、香蕉类、柚子类(继承水果,都属于水果)

数组初始化完成后,数组在内存中所占的空间将被固定下来,数组元素发生任何变化(包括清空),数组的长度将不可改变。
数组即可以存储基本数据类型,也可存储引用类型。只要所有的数组元素具有相同的类型即可。
数组是引用类型,即可以被另一个数组所存储。

定义数组

定义数组的两种形式:

type[] arrayname;
type arrayname[];

从可读性而言,第一种更能复合声明变量的形式,变量类型为type[],变量名为arrayname。

第二种是为了复合C语言的使用者,但是C#已经舍去了第二种声明方式。

为什么数组指定时不能指定长度?

数组是一种引用变量,定义一个数组时,仅仅只是定义了一个引用变量。这个引用变量还未指向任何有效的内存,此时定义的数组还不能指定数组长度。因为现在还未有内存空间来存储数组元素,因此这个数组还不能使用,只有初始化以后的数组才可以使用。

初始化数组

在Java语言中数组必须初始化才能使用,即为数组的数组元素分配内存空间,并为每个数组元素赋予初始值。

赋予初始值就有内存空间,但是有了内存空间也必须有初始值。

数组的初始化有如下两种方式:

静态初始化:初始化时由程序员显式的指定每个数组元素的初始值,由系统决定数组的长度。

动态初始化:初始化时数组长度由程序员指定或程序指定,由系统为元素分配初始值。

静态初始化

静态初始化语法
    数组类型[] 数组变量 = new 数组类型[]{数组元素1,数组元素2...,数组元素n};
第一种:
    type[] arrayName = new type[]{elem1,elem2};
第二种:
    type[] arrayName = {elem1,elem2};

1.声明数组类型与静态初始化指定的数组元素相同

//定义一个int[]类型的数组,并静态初始化。
int[] arrayInt = new int[]{1,2,3,4,5};
//上面的代码等价于下面的代码
int[] arrayInt1;
arrayInt1 = new int[]{1,2,3,4,5};
//上面的代码等价于下面的代码
int[] arrayInt2 = {1,2,3,4,5};

2.声明数组类型是静态初始化指定的数组元素类型的父类

//String类型是Object类型的子类
Object[] objectArr = new String[]{"张三","李四"};
//Object是一切类型的父类
//"1"是字符串类型
//1是int类型包装类为Integer
Object[] objectArr1= new Object[]{"1",1};

注意在实际开发中静态初始化推荐使用:

type[] arrayName = {elem1,elem2};
int[] arrayInt = {1,2,3,4};

动态初始化

动态初始化语法:
    数组类型[] 数组变量 = new 数组类型[数组长度];
    type[] arrayName = new type[length];

1.声明数组类型与静态初始化指定的数组元素相同

int[] arrayInt = new int[5];

2.声明数组类型是静态初始化指定的数组元素类型的父类

//String类型是Object类型的子类
Object[] objectArr = new String[2];

动态初始化时,系统给初始化数组分配的默认值:

基本类型:
    整数类型的默认值是:0
    浮点类型的默认值是:0.0
    字符类型的默认值是:'\u0000'
    布尔类型的默认值是:false
引用类型的默认值为null

注意:数组的静态初始化和动态初始化不能同时使用。

访问数组元素与数组的遍历

数组的索引

数组类型后面的[]中可以填写数组的索引值,索引值的范围为零至数组最大长度减1。

静态数组例子

public class J_ArrayDemo1 {
    public static void main(String[] args) {
        int[] arrInt = {1,2,3};
        //索引范围为0-2即0、1、2
        System.out.println(arrInt);//输出数组地址值
        System.out.println(arrInt[2]);//输出3
        System.out.println(arrInt[3]);//java.lang.ArrayIndexOutOfBoundsException数组索引越界异常
        System.out.println(arrInt[-1]);//java.lang.ArrayIndexOutOfBoundsException数组索引越界异常
    }
}

动态数组例子

public class J_ArrayDemo2 {
    public static void main(String[] args) {
        int[] arrInt = new int[10];
        //索引范围为0~9即0、1、2、3、4、5、6、7、8、9
        System.out.println(arrInt);//输出值为地址值
        System.out.println(arrInt[0]);//输出系统默认值0
        System.out.println(arrInt[4]);//输出系统默认值0
       // System.out.println(arrInt[-1]);//java.lang.ArrayIndexOutOfBoundsException数组索引越界异常
        System.out.println(arrInt[10]);//java.lang.ArrayIndexOutOfBoundsException数组索引越界异常
    }
}

数组长度属性 length

length是数组的长度属性,通过此属性可以获取数组的长度,然后依靠此属性可以查询(打印)数组的值以及动态的为数组赋值。

数组长度属性例子

//1.查询(打印)数组的值
public class J_ArrayDemo3 {
    public static void main(String[] args) {
        int[] arrayInt = new int[8];
        for (int i = 0; i < arrayInt.length; i++) {
            System.out.println(arrayInt[i]);
        }
    }
}
//2.数组赋值以及数组动态赋值
public class J_ArrayDemo4 {
    public static void main(String[] args) {
        //静态数组
        int[] arrayInt = {1,2,3};
        //替换数组arrayInt第二个元素的值为101
        arrayInt[1] = 101;
        System.out.println(arrayInt[1]);//输出101
        //动态数组
        long[] arrayLong = new  long[10];
        for (int i = 0; i < arrayLong.length ; i++) {
            System.out.println("赋值前"+arrayLong[i]);
            arrayLong[i] = i;
            System.out.println("赋值后"+arrayLong[i]);
        }
        System.out.println();
        System.out.println(arrayLong[2]);    
        String[] arrayStr = new String[4];
        arrayStr[0] = "王";
        arrayStr[1] = "张";
        for (int i = 0; i < arrayStr.length; i++) {
            System.out.println(arrayStr[i]);
        }
    }
}

遍历数组——数组和集合的专属循环foreach

foreach循环语法
    for(数组类型 变量:数组变量(集合变量)){
    //自动访问(迭代)每个元素
    }

使用forecah循环时无需获取数组长度和索引

public class J_ArrayDemo5 {
    public static void main(String[] args) {
        String[] books = {"春秋","战国","三国","红楼梦","聊斋"};
        for (String a : books) {
            System.out.println(a);
        }
    }
}

当然在使用foreach时通常不用对循环变量赋值,但是可以赋值(不推荐使用)

public class J_ArrayDemo5 {
    public static void main(String[] args) {
        String[] books = {"春秋","战国","三国","红楼梦","聊斋"};
        for (String a : books) {
            System.out.println(a);
        }
    }
}

循环变量赋值例子

public class J_ArrayDemo6 {
    public static void main(String[] args) {
        String[] books = {"春秋","战国","三国","红楼梦","聊斋"};
        for (String a : books) {
            a = "西游记";
            System.out.println("赋值变量了的数组值:"+a);
        }
        for (String a : books) {
            System.out.println("未赋值变量了的数组值:"+a);
        }
    }

上面两个代码对比可知,赋值了的数组中的元素的值都被”自学Java“覆盖了。

注意:使用foreach循环迭代数组元素时,不能对数组元素赋值。

堆与栈

栈:当一个方法执行时,会在内存栈中开辟一块属于自己的空间,此方法中的变量会放在此空间中,随着方法的结束变量和方法中的变量被销毁。

堆:在程序中创建一个对象时,这个对象将被保存到堆中,对象不会随着方法的结束而销毁,即使方法结束后,这个对象还可以被其他引用变量所引用,只有当没有被任何引用变量所引用时,才会在系统空闲时,被系统垃圾回收机制回收。

所有引用变量相同的是引用变量时访问真实对象的根本方式,即对数组而言,数组引用变量是访问堆内存中数组元素的根本方式。实际的数组对象存储在堆内存中,如果引用该数组对手的数组引用变量是一个局部变量,那么该局部变量存储在栈内存中。

public class J_ArrayDemo7 {
    public static void main(String[] args) {
        int[] arrayInt = new int[]{1,2,3,4};
        //运行此方法
        //栈内存开辟main方法空间
        //main方法空间生成数组引用变量arrayInt,同时堆内存开辟静态数组空间,长度为4,数组元素为1、2、3、4,并生成该空间的地址值
        //数组引用变量arrayInt指向堆空间的地址值
    }
    //main方法空间结束
    //arrayInt被销毁,数组对象无其他引用变量引用等待被销毁。
}
public class J_ArrayDemo8 {
    public static void main(String[] args) {
        int[] arrayInt = {1,2,3};
        System.out.println(arrayInt);//输出地址值
        arrayInt = null;//让数组引用变量指向null,数组对象无实际引用变量引用,会被系统垃圾回收机制收回。
        System.out.println(arrayInt);//打印null
    }
}

数组变短的错觉:

public class J_ArrayDemo09 {
    public static void main(String[] args) {
        int[] arrayInt = {1,2,3};
        int[] arrayInt2 = {1,2};
        System.out.println("arrayInt的地址值"+arrayInt);//arrayInt的地址值[I@7291c18f
        System.out.println("arrayInt的长度为"+arrayInt.length);//arrayInt的长度为3
        System.out.println("arrayInt2的地址值"+arrayInt2);//arrayInt2的地址值[I@27bc2616
        System.out.println("arrayInt2的长度为"+arrayInt2.length);//arrayInt2的长度为2
        arrayInt = arrayInt2;
        System.out.println("arrayInt的地址值"+arrayInt);//arrayInt的地址值[I@27bc2616
        System.out.println("此时arrayInt的长度为"+arrayInt.length);//此时arrayInt的长度为2
    }
}

上述代码中因为arrayInt的地址值的指向重新修改为arrayInt2的地址值,因此看似长度变短了,但是其实质对象变化了。

public class J_ArrayDemo10 {
    public static void main(String[] args) {
        int[] a = {5,7,20};
        int[] b = new int[4];
        System.out.println("b的数组长度为"+b.length);
        for (int i = 0; i < a.length; i++) {
            System.out.println(a[i]);
        }
        for (int i = 0; i < b.length; i++) {
            System.out.println(b[i]);
        }
        b=a;
        System.out.println("b的数组长度为"+b.length);
    }
}

基本类型的初始化

public class J_ArrayDemo11 {
    public static void main(String[] args) {
        int[] iArr = new int[5];
        //定义一个数组变量(int[] iArr),并在栈内存开辟iArr空间,指向一个空引用,
        //执行new int[5]时,在堆内存分配内存空间并分配默认初始值为0,生成该空间的地址值([I@723279cf)
        //指向完整语句后引用变量iArr指向[I@723279cf
        System.out.println(iArr);//打印地址值
        for (int i = 0; i < iArr.length; i++) {
            iArr[i] = i + 10;//动态的将堆内存中的默认初始值0更改为i+10,10,11,12,13,14
        }
    }
}

引用变量的初始化

class Person{
    public int age;
    public double height;
    public void info(){
        System.out.println("我的年龄是"+age+",我的身高是"+height);
    }
}
public class J_ArrayDemo12 {
    public static void main(String[] args) {
        Person[] student = new Person[2];
        Person zhangsan = new Person();
        zhangsan.age = 15;
        zhangsan.height = 158;
        Person lee = new Person();
        lee.age = 16;
        lee.height = 161;
        student[0] = zhangsan;
        student[1] = lee;
        lee.info();
        student[1].info();
    }
}

多维数组

多维数组实质是可以看作为一维数组来看待。

        一维数组:int[] a;
        二位数组:int[][] b;
        三维数组:int[][][] c;
        int[] a = {1,2};
        int[][] b = {{0,1},{1,2},{2,3}};
        int[][][]c = {{{1,2},{3,4},{5,6}},{{7,8},{9,10},{11,12}}};
        二维数组可以这么理解,数组类型 [ 二维数组(行) ] [ 一维数组(列)]。

二维数组的初始化

public class J_ArrayDemo14 {
    public static void main(String[] args) {
        int[][] arrayInt = {{1},{2,3},{4,5,6}};
        int[][] arrayInt2 = new int[4][4];
        for (int i = 0; i < arrayInt2.length ; i++) {
            for (int j = 0; j < arrayInt2.length; j++) {
                arrayInt2[i][j] = i+j;
                System.out.println("i的值为:"+i);
                System.out.println("j的值为:"+j);
                System.out.println(arrayInt2[i][j]);
            }
        }
    }
}

二维数组的遍历

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

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表