数据结构——数组篇java版(完整+简洁+通俗易懂)

一、数组的基本概念

1、什么是数组

指的是一种容器,可以同来存储同种数据类型的多个值。

但是数组容器在存储数据的时候,需要结合隐式转换考虑。

比如:

定义了一个int类型的数组。那么boolean。double类型的数据是不能存到这个数组中的,

但是byte类型,short类型,int类型的数据是可以存到这个数组里面的。

建议:

容器的类,和存储的数据类型保持一致。

举例:

整数1 2 3 4 56 就可以使用int类型的数组来存储。

小数1.1 1.2 1.3 1.4 就可以使用double类型的数组来存储。

字符串"aaa" "bbb" "ccc" 就可以使用String类型的数组来存储。

2、数组的创建

创建一个数组:

T[] 数组名; 比如 int[] array;

T 数组名[]; 比如 int array[] ;

3.数组的静态初始化

完整格式:

int[] arr = new int[]{11,22,33};

double[] arr = new double[]{1.1,1.2,1.3};

简化格式:

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

double[] array = {1.1,1.2,1.3};

知道数组的内容,就可以静态初始化。

4.数组的动态初始化

//1.定义一个数组,存3个人的年龄,年龄未知 int[] agesArr = new int[3];

如果不知道数组的内容,那么就可以使用动态初始化。

如果对数组进行动态初始化,数组中的元素有默认值。不同的数据类型有不同的默认值,如果是简单类型,大多是默认值为0。float是0.0f,double是0.0,char是/u0000,boolean是false;引用类型比如字符串类型则是null。

二、一维数组的使用

1、数组元素的访问

数组在内存中是一段连续的空间,下标是从0开始的。

数组是一段连续的内存空间,因此支持随机访问,即通过下标访问快速访问数组中任意位置的元素。数组的下标从0开始,介于[0, N)之间不包含N,N为元素个数,不能越界,否则会报出下标越界异常。
2、数组的遍历

在Java中,对数组的遍历有两种方式:第一种是for,第二种是增强for(foreach)。

由于Java是面向对象的语言,在Java中,一切都是对象,比如数组。数组这个对象有它的属性,比如数组的长度等,基于这一点,我们可以不用刻意知道数组的长度,使用.length来获取数组的长度。
//for
int[]array = new int[]{10, 20, 30, 40, 50};
for(int i = 0; i < array.length; i++){
    System.out.println(array[i]);
}
//foreach
int[] array = {1, 2, 3};
for (int x : array) {
    System.out.println(x);
}

增强for循环是得不到数组的下标的,所以它一般用于数组的遍历,比如数组累加这样的操作。

三、数组在内存中的分布

1、JVM内存分布简介

要了解数组在内存里面的情况,就要知道Java内存分布是什么样的,这里做必要的介绍。Java经过编译后产生的.class文件被加载到JVM虚拟机里面的本地方法栈里面运行。为了高效管理内存,JVM对内存进行了划分。JVM是一个软件,由C/C++编写的软件。这是因为系统之类的由C/C++代码编写比较高效。

说明:

(1)Java虚拟机栈:也是我们在Java中常说栈。一般用来存放局部变量。

(2)本地方法栈:运行由c/c++编写的代码。经过编译产生的.class文件被加载到这里运行。

(3)堆:是Java中最大的一块内存空间。只要是对象,都是在堆上开辟的。在堆里面的引用叫对象。堆上的内存是不需要进行手动释放的,Java有自己的垃圾回收机制。

(4)程序计数器:保存一些指令和信息等。

(5)方法区:存放常量,静态成员变量等。

这里重点关心堆和虚拟机栈。

2、引用类型变量

引用类型创建的变量,一般称为对象的引用。存储的是对象所在空间的地址。如何理解数组的引用呢?比如写了这么一个代码:

int[] arr = new int[] {1,2,3};
System.out.println(arr);//[I@14514713

在内存中发生了什么呢?

这里的arr是局部变量,运行代码后,java就会在栈上为arr分配空间。后面new了之后,就会在堆上开辟一块空间来保存这些内容。arr存的是后面对象的地址。这里要强调的是,引用变量存的是对象的地址。

现在我们直接打印arr输出了:[I@14514713

打印出了这么一个地址(可以理解为数组首元素地址)。这里的地址为了安全,经过了特殊的处理,是这个引用对象的哈希地址。@之后的是哈希地址,@前的I表示这是一个int型,[表示是一个数组。arr这个引用,引用(指向)了一个数组对象。在比如以下代码:
int[] arr = new int[] { 1,2,3,4 };
int[] brr = arr;//???
System.out.println(arr);//[I@14514713
System.out.println(brr);//[I@14514713

这里打印出来的地址是一样的,说明brr也引用了与arr相同的对象。

四、二维数组

1、二维数组定义

二维数组本质上也就是一维数组,只不过每个元素又是一个一维数组。

数据类型 数组名称 = new 数据类型 行数 { 初始化数据 };

int arr1 = { {1,2,3},{4,5,6} }; int arr2 = new int { {1,2,3},{4,5,6} }; int arr3 = new int2; int arr4 = new int2; 在Java中,如果是前两种定义的方式,必须要手动加括号。同时,行是必须要指定的,列可以不用指定。

2、二维数组遍历

和一维数组类似,二维数组有for循环和foreach循环来进行遍历。

    int[][] arr1 = { {1,2,3},{4,5,6} };
    //for
    for (int i = 0; i < arr1.length; i++) {
        for (int j = 0; j < arr1[i].length; j++) {
            System.out.print(arr1[i][j] + " ");
     }
    System.out.println();
 }
    //foreach
    for (int[] x : arr1) {
        for (int y : x) {
          System.out.print(y + " ");
         }
     System.out.println();
}

五、数组常用的方法

//导入包
import java.util.Arrays;
​
public class Main {
    public static void main(String[] args) {
        //1、Arrays.toString方法
        //将一维数组变成字符串。二维数组使用Arrays.deepToString方法。
        int[] array=new int[]{1,2,3,4};
        System.out.println(array);//[I@14514713
        System.out.println(Arrays.toString(array));//[1, 2, 3, 4]
​
        //2.1、Arrays.copyOf方法
        //从0下标来复制指定长度数组的内容到新的数组中。
        int[] array1=Arrays.copyOf(array,2);
        System.out.println(Arrays.toString(array1));//[1,2]
​
        //2.2、Arrays.copyOfRange方法
        //和Arrays.copfOf方法类似,这个是指定范围的拷贝。范围是左闭右开区间。
        int[] array2=Arrays.copyOfRange(array,2,4);
        System.out.println(Arrays.toString(array2));//[3, 4]
​
        //3、Arrays.sort方法
        //对数组进行升序排序。
        int[] ret={2,1,4,3};
        Arrays.sort(ret);
        System.out.println(Arrays.toString(ret));//[1, 2, 3, 4]
​
        //4、Arrays.fill方法
        //对数组内容进行指定填充。
        int[] ret1=new int[10];
        Arrays.fill(ret1,6);
        System.out.println(Arrays.toString(ret1));//[6, 6, 6, 6, 6, 6, 6, 6, 6, 6]
        Arrays.fill(ret1,1,3,8);//左闭右开
        System.out.println(Arrays.toString(ret1));//[6, 8, 8, 6, 6, 6, 6, 6, 6, 6]
​
        // 5、Arrays.equal方法
        //判断两个数组的内容是否相同
        int[] ret2={6, 8, 8, 6, 6, 6, 6, 6, 6, 6};
        boolean equals = Arrays.equals(ret1, ret2);
        System.out.println(equals);//true
​
        // 6、Arrays.binarySearch方法
        //二分查找数组内容,使用前先sort排序数组。
        int[] ret3={4,1,3,2};
        //先进行从小到大排序
        Arrays.sort(ret3);
        //二分查找
        int i = Arrays.binarySearch(ret3, 3);
        System.out.println(i);//返回索引2
    }
}
  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值