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

java实现动态数组

概述

概述

实现

package com.lovehena.datastructure;

import lombok.extern.slf4j.Slf4j;

/*
*   java实现一个动态数组
*       实际上,java.util.ArrayList这个类就是一个动态数组的类
*       和静态数组最大的不同就是,java.util.ArrayList中的元素个数是可以变化的。
*
*   一个动态数组中至少要有3个属性:
*       1.size 动态数组中已有元素的个数
*       2.capacity 动态数组中最大的元素个数
*       3.arr 虽然我们要实现的是一个动态数组,但还是需要一个静态数组用于存储元素,当静态数组无法容纳更多元素时动态扩容,于是,动态数组就实现了
*
*   先实现以下3个方法:
*       1.add(int index,int element) 往数组中指定索引处添加元素
*       2.addLast(int element) 将欲添加的元素添加到数组最后面
*       3.print() 数组的遍历
* */
@Slf4j
public class MyArrayList {
    private int size = 0; // 动态数组中已手动添加的元素的个数 初始时一个手动添加的元素也没有
    private int capacity = 10; // 动态数组中最大的元素个数 默认为10 java.util.ArrayList的默认初始容量也是10
    // 初始化一个静态数组 用于存储元素
    // 数组中的元素类型默认都是整数 如果需要存储其他类型 可以利用泛型机制实现
    // 实际上 int[] arr=new int[capacity] 这行代码执行完时 arr中已经有10个元素了 并且每个元素的值都是0
    private int[] arr = new int[capacity];

    /**
     * 往数组中指定索引处添加元素
     *  思路:
     *      已有数组
     *    元素  1 2 3 4 5
     *    索引  0 1 2 3 4
     *
     *      现在要往索引为2的位置添加一个元素100,则 3 4 5这3( 3 = size - index )个元素都要往后移动1位,将索引为2的位置空出来,再将目标元素插入在索引2处即可
     *      保证占用的内存空间是连续的
     * @param index 目标索引
     * @param element 目标元素
     */
    public void add(int index, int element) {
        if (index < 0 || index >= capacity) { // index最大值为capacity-1 最小值为0
            log.error("索引:{} 不正确", index);
            return;
        }
        // 利用System.arraycopy完成数组中元素的移动 api不熟悉的话可以点进源码阅读下注释
        // destPos的最大值为index(而不是index+1 java api设计中大多都是含头不含尾)
        System.arraycopy(arr, index, arr, index + 1, size - index);
        arr[index] = element;
        size++; // 已手动添加的元素的个数+1 这个size其实类似于实现链表时的头节点(头指针)
    }

    /*
    *   1 2 3 4 5 6 7 8 9 10
    *   0 1 2 3 4 5 6 7 8 9
    *
    * */

    /**
     *  将欲添加的元素添加到数组最后面
     *      思路:
     *        已有数组
     *      元素  1 2 3 4 5
     *      索引  0 1 2 3 4
     *
     *      现在要将6插入到数组的最后面,即插入到索引为5( size = 5)的位置,所以调用add传入index为size即可
     *
     *      实际上 很多代码的书写都是先总结规律 再写出来的
     * @param element 欲添加的元素
     */
    public void addLast(int element){
        // 直接调用add方法即可
        add(size,element);
    }

    /**
     *  数组遍历
     */
    public void print(){
        /*
            为什么不是这么写?
            for (int i = 0; i < arr.length; i++) {

            }
            因为 数组中真正添加了几个元素是由size表示的 我们遍历时需要的是我们手动添加的元素
            而不是数组初始化时默认初始化的为0的元素
         */
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < size; i++) {
            sb.append(arr[i]).append(" ");
        }
        log.info("遍历数组 数组为:{}\n",sb.toString());
    }

    //todo 扩展:数组遍历的逻辑由调用者自定义,而不是直接写死在print()中,如何实现?
    //todo 扩展:以上的代码和动态数组(动态扩容)还没关系,感兴趣的朋友可以自己先实现下。
}

测试用例

@Slf4j
public class TestMyArrayList {
    public static void main(String[] args) {
        MyArrayList list = new MyArrayList();
        list.add(0,1);
        list.add(1,2);
        list.add(2,3);
        list.print();
        list.addLast(4);
        list.print();
    }
}

测试用例输出

测试用例输出

扩展

数组遍历的逻辑由调用者自定义,而不是直接写死在print()中,如何实现?

以上的代码和动态数组(动态扩容)还没关系,感兴趣的朋友可以自己先实现下。

最后

好了,如果对你有帮助的话,欢迎点个免费的赞哦。

相关文章:

  • wps中zotero插件消失,解决每次都需要重新开问题
  • 【C++】在线五子棋对战项目网页版
  • Python之numpy
  • 【CS285】高斯策略对数概率公式的学习笔记
  • 【python】conda命令合集
  • Java版企电子招标采购系统源业码Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis
  • <02.21>八股文
  • 01 1个路由器+两个子网
  • Leetcode 二叉树展开为链表
  • c++:stack与deque
  • 基于Java+SpringBoot+Vue的前后端分离的汉服推广网站
  • HW面试经验分享 | 北京蓝中研判岗
  • 算法:选择排序(以排队为例)
  • git 克隆及拉取github项目到本地微信开发者工具,微信开发者工具通过git commit、git push上传代码到github仓库
  • 6.z字形变换(python)
  • 【消息队列】认识项目
  • 如何确定服务器是否被黑客入侵爆破
  • GO系列-IO 文件操作
  • 第三章 STM32 IIC驱动
  • 模电知识点总结(6)
  • 新任重庆市垫江县委副书记刘振已任县政府党组书记
  • 多少Moreless:向世界展示现代中式家具的生活美学
  • 贵州仁怀通报“正新鸡排鸡腿里全是蛆”:已对同类产品封存送检
  • 美将解除对叙利亚制裁,外交部:中方一贯反对非法单边制裁
  • 绿景中国地产:洛杉矶酒店出售事项未能及时披露纯属疏忽,已采取补救措施
  • 七旬男子驾“老头乐”酒驾被查,曾有两次酒驾两次肇事记录