前言

如果数据(变量)过于分散,就不便于统一管理

容器可以把多个相同数据类型的数据(变量)集中组织到一起,便我于们对多个数据进行统一管理

容器有以下特点:

  • 容器可以保存多个数据类型相同的元素
  • 容器的大小固定不可改变

 

一、数组的概念

Java中的容器有很多种,而数组就是容器的一种,数组具有容器的所有特点。

  • 数组中可以保存多个相同数据类型的元素。
  • 数组的长度一旦确定不可以改变。

 

二、数组的2种声明方式

Java有2种声明数组的方法,1种继承自C语言,另一种是目前Java中主流的数组声明方式。

1.C语言数组声明风格(不建议使用)

int array2[];

 

2.Java数组声明风格

int array2[];

 

三、数组的2种初始化方式

和Python不同Java是强类型语言,如果想要使用变量必须声明变量的数据类型。

为了避免在写代码的过程中反复声明变量数据类型,变量声明 和 初始化(赋值))可以分成2步,也就是先声明,再初始化(赋值)。

Java中有整数、字符、布尔、字符串、空(null)6种常量,空常量不能打印。

空常量和基本数据类型没关系(基本数据类型在栈中存储),使用空常量(null)可以给引用数据类型的对象引用进行赋值。

如果数组只声明 不初始化(赋值),该数组的引用会在栈空间中指向常量null,并不会开辟堆内存空间;

如果数组没有指向任何堆内存地址值, 我们还试图去使用该数组时,就会出现空指针异常。

 

1.动态初始化数组

        byte[] byteArray = new byte[3];//当初始化数组时,数组长度可以设置为变量、运算结果。
        int length = 3;
        int[] intArray = new int[length];

 

2.静态初始化数组

如果创建数组时,如果可以直接确定数组中的内容,可以静态初始化数组。

相较于动态初始化数组,静态初始化数组方式不需要指定数组长度,JVM会自动根据{}中元素的个数,自动推导出数组长度。

静态初始化数组分为完整格式初始化和简化格式初始化2种方法。

A.完整格式初始化数组

数组静态初始化:创建数组时,直接确定数组元素。(不需要指定数组的长度JVM会根据{}中元素的个数自动推导出数组长度)

 //静态初始化数组
 byte[] byteArray = new byte[]{1, 2, 3};

B.简化格式初始化数组

虽然静态简化初始化的格式不需要有new,但是底层仍然有开辟空间的过程。

//静态初始化简化版,底层依然new了开辟了内存空间
int[] intArray = {1011, 1024};

注意:

 通过静态初始话数组简化格式,只能一步就完成数组的声明和初始化,无法对已经声明的数组再进行初始化。

        int[] intArray;
        intArray = new int[2];              //动态初始化数组
        intArray = new int[]{10, 29,22};    //静态初始化数组(完整格式)
        //intArray = {1, 2, 3}              //静态初始化数组(简化格式)无法对提前声明的数组进行初始化。

 

四、数组原理内存图

以上我们通过声明+初始化完成了数组变量的定义,那么JVM是怎么实现这个过程的呢?

Java字节码存储在硬盘中,一旦程序需要运行起来Java虚拟机会把程序加载到内存中,以供CPU快速执行程序。

Java虚拟机要运行程序,就需要提前申请一大块内存空间,并对内存进行空间的分配和管理。

为了提升运算效率,JVM对申请的内存空间进行不同区域划分,每一片区域都有特定的处理数据方式和内存管理方式。

  • 寄存器:CPU获取和存储数据的内存,给CPU使用。
  • 本地方法栈:JVM使用操作系统功能时使用。
  • 方法区:存储可以运行的class文件
  • 堆内存:存储对象或者数组,new出来的都存储在堆内存
  • 栈内存:方法执行时使用的内存空间,比如main方法运行,进入方法栈中执行。
 int[] intArray1=new int[]{1,23,66};

Java的基本数据类型保存在栈内存,引用数据类型保存在堆内存。

当我们创建数组intArray1时JVM会把先main方法加载到栈内存执行。

执行到方法中new语法时,开辟一块堆内存存储数据{1,23,66}这块真正存储数据的堆内存空间称为对象

intArray1在栈内存中保存了对象(堆内存)的内存地址值,固intArray1为对象的引用

new进堆,左进栈,栈里的引用堆里的内存地址。

 

五、数组元素的访问方式

Java数组只对外提供了1种访问方式-索引方式,索引-数组中元素的编号,该编号(索引)默认从0开始,正序递增,恒为正数。

只有通过数组的索引,才能设置和获取数组中的元素,因此索引才是实现数组元素统一管理的核心

数组元素求和、求最大、求最小、求均值以及排序操作,都是通过for循环生成正确的数组索引实现的。

 

1.数组元素排序

public class ArrayDemo15 {
    public static void main(String[] args) {
        int[] intArrary = {18, 20, 15, 17};
        for (int i = 0; i < intArrary.length; i++) {
            int currentMax;
            for (int j = i + 1; j < intArrary.length; j++) {
                if (intArrary[i] > intArrary[j]) {
                    currentMax = intArrary[i];
                    intArrary[i] = intArrary[j];
                    intArrary[j] = currentMax;

                }
            }
        }
        System.out.println(Arrays.toString(intArrary));
    }
}

 

2.获取数组中的最大值和最小值

获取数组中最大值和最小值是需使用2个独立的if分支。

在1次for循环中判断2次,1次判断当前最大值,另一1次判断当前最小值,因为比当前最大值的数小的数,不一定就是整个数组中最小的数。

//获取数组中的最大值和最小值。----【纪念2017年冬,地铁13号线望京西 面试】
public class ArrayDemo14 {
    public static void main(String[] args) {
        int[] intArray = new int[]{-11, 8115, 12, -117, -20};
        int maxNumber = intArray[0];
        int minNumber = intArray[0];
        for (int i = intArray.length - 1; i >= 0; i--) {
            int currentElement = intArray[i];
            //1.要使用2个独立的if分支
            if (currentElement > maxNumber) {
                maxNumber = currentElement;
            }
            /*
            2.不能在此处直接使用else{因为比当前最大的数小的数,不一定就是整个数组中最小的数字 }
            因此需要1次for循环需要判断2次,1次判断当前最大,1次判断当前最小
            */
            if (currentElement < minNumber) {
                minNumber = currentElement;
            }
        }
        System.out.println("当前数组的最大值" + maxNumber);
        System.out.println("当前数组的最小值" + minNumber);
    }

 

3.数组append元素

 在Java中数组长度是固定的,需要创建新的数组实现;

package ArryOpration;

import java.util.Arrays;

public class TestArray {
    public static void main(String[] args) {
        String[] l1 = {"我", "是"};
        String[] l2 = {"张", "根"};
        String[] l3 = new String[l1.length + l2.length];
        for (int i = 0; i < l1.length; i++) {
            l3[i] = l1[i];
        }
        for (int i = 0; i < l2.length; i++) {
            l3[l1.length + i] = l2[i];
        }
        //把l3的内存地址赋值给l1
        l1=l3;
        System.out.println(Arrays.toString(l1));
    }

}

 

4.数组remove元素

在Java中数组长度是固定的,需要创建新的数组实现;

re-重新-move移动,重新移动了=删除;

方案1:

package ArryOpration;

import java.util.Arrays;

//删除数组中的某个元素
public class TestArray01 {
    public static void main(String[] args) {
        int[] array1 = {3, 4, 5, 6, 2, 7, 8, 9};
        //删除索引为2的元素
        int del_index = 2;
        //step1:从删除的位置开始,向前移动元素
        for (int i = del_index; i < array1.length - 1; i++) {
            array1[i] = array1[i + 1];
        }
        //step2:将最后1个闲置位的元素,置为0;
        array1[array1.length - 1] = 0;
        System.out.println(Arrays.toString(array1));

    }

}

方案2:

package ArryOpration;

import java.util.Arrays;

public class TestArray02 {
    public static void main(String[] args) {
        int[] array1 = {1, 9, 9, 8, 0, 5, 8, 9};
        //删除索引为5的元素
        int del_index = 5;
        //step1:创建1个新的数组
        int[] new_array = new int[array1.length - 1];
        //step2:移动目标索引之前的元素;
        for (int i = 0; i < del_index; i++) {
            new_array[i] = array1[i];
        }
        System.out.println(Arrays.toString(new_array));
        //step3:移动目标索引之后的元素;
        for (int i = del_index + 1; i < array1.length; i++) {
            new_array[i - 1] = array1[i];
        }
        //step4:使array1栈内存存储的引用地址和new_array相同;
        array1 = new_array;
        System.out.println(Arrays.toString(array1));
    }
}

  

5.冒泡排序

我们喝汽水的时候,由于二氧化碳比水轻,汽水里面会不断有小气泡,向上浮到汽水上面。

冒泡排序算法可以将集合中的 每一个数字元素都像小气泡一样,一点一点地向数组的一侧(右侧/左侧)移动。

冒泡排序核心思想:让数组中相邻的2个数字元素,进行两两比较,根据大小交换位置,使较大数字元素逐渐向一侧移动。

package com.itheima.sort;

import java.util.Arrays;

//基本排序-冒泡排序
/*
 *我们喝汽水的时候,由于二氧化碳比水轻,汽水里面会不断有小气泡,向上浮到汽水上面。
 *冒泡排序算法可以将集合中的 每一个数字元素都像小气泡一样,一点一点地向数组的一侧(右侧/左侧)移动。
 * 冒泡排序核心思想:让数组中相邻的2个数字元素,进行两两比较,根据大小交换位置,使较大数字元素逐渐向一侧移动。
 * */
public class BubbleSortDemo1 {
    public static void main(String[] args) {
        int[] intArray = {5, 8, 6, 3, 92, 1, 7};
        for (int i = 0; i < intArray.length - 1; i++) {
            //相邻的两个元素进行大小对比
            if (intArray[i] > intArray[i + 1]) {
                //交换位置
                int temp = intArray[i];
                intArray[i] = intArray[i + 1];
                intArray[i + 1] = temp;
            }
        }
        /*
         *1次循环(打擂)只能在组中确定1个座次(按大小排序的座次)(内循环)
         *执行数组长度-1次循环就可以完成数组中所有数字元素的排位(外循环)
         */
        for (int i = 0; i < intArray.length; i++) {
            for (int j = 0; j < intArray.length - i - 1; j++) {
                //相邻的两个元素进行大小对比
                if (intArray[j] > intArray[j + 1]) {
                    //交换位置
                    int temp = intArray[j];
                    intArray[j] = intArray[j + 1];
                    intArray[j + 1] = temp;
                }

            }
            System.out.println(Arrays.toString(intArray));

        }



    }
}
冒泡排序

 

六、Arrays数组工具类

JRE提供了1个叫Arrays的工具类,封装了排序、查找极值、遍历输出等功能,可以帮助我们对数组进行操作;

package ArryOpration;

import java.util.Arrays;

public class TestArray {
    public static void main(String[] args) {
        int[] bag2 = new int[]{6, 17, 82, 9, 10};
        //显示数组
        int[][] bag1 = new int[][]{{1, 2}, {3, 4}};
        for (int[] a : bag1) {
            System.out.println(Arrays.toString(a));
        }
        System.out.println(Arrays.toString(bag1));
        System.out.println(Arrays.toString(bag2));
        //通过二分法,对数组进行排序然后再获取元素的索引
        Arrays.sort(bag2);
        System.out.println(Arrays.toString(bag2));
        System.out.println(Arrays.binarySearch(bag2, 9));
        //切片数组中的元素
        int[] new_array = Arrays.copyOf(bag2, 4);
        System.out.println(Arrays.toString(new_array));
        //区间切片
        int[] new_array1 = Arrays.copyOfRange(bag2, 1, 4);
        System.out.println(Arrays.toString(new_array1));
        //判断2个数组中的值是否相等?
        int[] array1 = {1993, 0};
        int[] array2 = new int[]{1993, 0};
        System.out.println(Arrays.equals(array1, array2));
        //从数组1中复制元素到数组2
        int[] src_array = new int[]{1, 2, 3, 4};
        int[] des_array = new int[10];
        //将源数组下标位1开始,复制到目标数组的下标3,一共复制3个元素
        System.arraycopy(src_array, 1, des_array, 3, 3);
        System.out.println(Arrays.toString(des_array));

    }

}

 

 

七、二维数组

在机器学习中数据集最终会变成1个数字类型二维数组;

但是我在Python里定义二维数组时,思维是由外至内的;[ [1,2,3],[2,4,5,9] ];

在Java中定义二维数组时思维是由内向外:1个int圈起来=int[]=数组,再把数组圈起来=int[][]=1个二维数组;

package ArryOpration;

import java.util.Arrays;

public class TestArray {
    public static void main(String[] args) {
        String[][][][] a1 = {{{{}}}};
        System.out.println(Arrays.toString(a1));

    }

}

 

 

 

 

 

参考

posted on 2021-10-23 10:27  Martin8866  阅读(110)  评论(0编辑  收藏  举报