当前位置: 首页 > article >正文

数组的实现原理(Java版)

 

目录

一.数组是什么?

内存分配:

特点:

数组的实现原理:

时间复杂度:

二.Java数组的实现:

总结:


一.数组是什么?

数组(Array) 是一种数据结构,用于存储相同类型的元素集合。数组在内存中是连续分配的,所有的元素都使用相同的数据类型,并且可以通过下标(索引)来访问特定元素。数组是一种常见的线性数据结构,适合用于高效的随机访问操作。

内存分配:

//8字节的markword
//4字节的class指针(压缩class指针的情况)
//4字节的数组大小(决定了数组最大容量是2的32次方)
//java中所有的对象大小都是8字节的整数倍,不足的要用对齐字节补足
//int[] array = {1,2,3,4,5} => 8 + 4 + 4 + 5 * 4 + 4(alignment补齐) = 40字节

特点:

  1. 固定大小:数组在创建时需要指定大小,大小一旦确定,不能更改。
  2. 连续内存空间:数组的元素在内存中是连续存储的,这使得它在读取时可以快速通过索引定位。
  3. 索引从0开始:数组的索引是从0开始的,第一个元素的索引是0,最后一个元素的索引是 长度 - 1
  4. 相同类型元素:数组中的所有元素必须是相同的数据类型。

数组的实现原理:

  • 存储结构:数组在内存中以连续的地址空间存储。假设数组的起始地址为 base_address,每个元素的大小为 size,则索引为 i 的元素的地址为 base_address + i * size。这使得数组可以通过索引在常数时间内(O(1))访问任意元素。

  • 访问时间复杂度:由于数组元素在内存中的地址是可以直接计算的,数组的读取操作(通过索引)时间复杂度为 O(1),即随机访问非常高效。

  • 缺点:由于数组大小固定,插入和删除操作在数组中相对较慢,特别是当需要在数组中间插入或删除元素时,时间复杂度为 O(n)

时间复杂度:

访问元素O(1)直接通过索引访问
修改元素O(1)直接通过索引修改
查找元素O(n)必须遍历整个数组(线性查找)
插入元素O(n)插入元素需要移动后续元素
删除元素O(n)

删除元素后需要移动后续元素

二.Java数组的实现:

Java的数组扩容机制:先创建更大容量的数组,然后将原来数组内的元素复制到新的数组,以此用新数组代替旧数组。

package ArrayStudy;

import java.util.Arrays;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.stream.IntStream;

public class ArrayListCreateCode implements Iterable<Integer> {
    //创建动态数组ArrayList
    //size => 动态数组有效元素个数
    //容量扩容 => 先创建更大容量的数组,然后将原来数组内的元素复制到新的数组,以此用新数组代替旧数组

    private int size = 0;//逻辑大小
    private int capacity = 8;//容量
    private int[] array = {};//空数组,懒加载(刚开始没用就不数组的情况就不会加载,如果需要此数组就)

    //新增元素
    public void addList(int element){
//        array[size] = element;
//        size++;
        add(size, element);
    }

    // 插入元素
    public void add(int index,  int element){
        checkAndGrow();
        // 添加逻辑
        if(index >= 0 && index < size){
            //数组间或数组内的元素拷贝(想要拷贝的数组,从哪拷贝,拷贝到的数组,拷贝到的数组的索引位置开始拷贝,拷贝元素个数)
            System.arraycopy(array,index,
                    array,index + 1,size - index);
        }
        array[index] = element;//插入元素
        size++;
    }

    private void checkAndGrow() {
        if(size == 0){
            array = new int[capacity];
        }else if(size == capacity){
            // 进行扩容 1.5倍
            capacity += capacity >> 1;
            int[] newArray = new int[capacity];
            System.arraycopy(array, 0, newArray, 0, size);
            array = newArray;// 新数组取代旧数组
        }
    }

    // 获取元素
    public int get(int index){
        return array[index];
    }


    // 遍历数组 => 以函数式接口的形式写出
    public void foreach(Consumer<Integer> consumer){
        for(int i = 0; i < size; i++){
            System.out.println(array[i]);
            // 返回void
            // 提供array[i]
            // 上两条分析后可以使用Consumer
            consumer.accept(array[i]);
        }
    }

    // 迭代器遍历
    @Override
    public Iterator<Integer> iterator(){
        // 匿名内部类
        return new Iterator<Integer>() {
            int i = 0;
            @Override
            public boolean hasNext() {// 有没有下一个元素
                return i < size;
            }

            @Override
            public Integer next() {// 返回当前元素,并移动到下一个元素
                return array[i++];
            }
        };
    }

    // (整数)流的遍历
    public IntStream stream(){
        return IntStream.of(Arrays.copyOfRange(array,0,size));// 选择有效部分流式返回
    }

    // 删除元素
    public int remove(int index){
        int removed = array[index];
        System.arraycopy(array,index + 1,
                array,index,size - index - 1);
        size--;
        return removed;
    }
}

总结:

  • 数组 是存储相同类型数据的基本数据结构,它提供了高效的随机访问。
  • 数组的主要操作包括访问、修改、遍历、获取长度等。
  • 数组的时间复杂度很高效(访问O(1),但插入和删除需要O(n))。

http://www.kler.cn/news/325134.html

相关文章:

  • 分享几个可以免费使用GPT的网站【2024年必备】
  • 计算机知识科普问答--20(96-100)
  • 【Python】import 引入常用模块
  • 编程练习:探索数学问题的编程解决方案 P137
  • Unity中的功能解释(数学位置相关和事件)
  • android13 系统默认设置静态IP
  • VMware下Ubuntu找不到共享文件夹
  • 4. 将pycharm本地项目同步到(Linux)服务器上——深度学习·科研实践·从0到1
  • Latex 自定义运算符加限定条件的实现
  • WPF入门教学十 资源与字典
  • Rust结构体初探
  • linux中实现多路复用服务器
  • 使用Python创建EXE运行器和截图工具
  • 【数据结构和算法实践-排序-总结】
  • 9.24作业
  • Uniapp 打包后的横屏控制
  • 【JavaEE初阶】多线程7(面试要点)
  • MacOS安装MindSpore(2024年最新)
  • 创意实现!在uni-app小程序商品详情页轮播中嵌入视频播放功能
  • 成都睿明智科技有限公司可靠吗?
  • SpringBoot--为什么Controller是串行的?怎样才能并行?
  • uni-app之旅-day01-home页
  • Python 课程18-SQLAlchemy
  • Stable Diffusion绘画 | LCM模型:实现秒出图
  • 多旋翼无人机光伏发电站吊运技术详解
  • nodejs基于vue电子产品商城销售网站的设计与实现 _bugfu
  • 19 vue3之自定义指令Directive按钮鉴权
  • Qt --- 其他控件的介绍 --- 多元素控件
  • 【在Linux世界中追寻伟大的One Piece】验证TCP
  • 数据工程师岗位常见面试问题-1(附回答)