欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java自定義一個變長數(shù)組的思路與代碼

 更新時間:2022年12月29日 12:55:39   作者:余數(shù)kl  
有時我們希望將把數(shù)據(jù)保存在單個連續(xù)的數(shù)組中,以便快速、便捷地訪問數(shù)據(jù),但這需要調(diào)整數(shù)組大小或者對其擴展,下面這篇文章主要給大家介紹了關(guān)于Java自定義一個變長數(shù)組的思路與代碼,需要的朋友可以參考下

前言

首先需要聲明的是,Java本身是提供了變長數(shù)組的,即ArrayList。那么自定義一個變長數(shù)組有啥用?其實沒啥用或者說用處不大,主要就是為了了解下變長數(shù)組的設(shè)計理念而已。實際工作中直接使用ArrayList。

思路分析

主要功能點:

  1. 新建時可以指定容量大小,不指定時使用默認容量大小。
  2. 向數(shù)組中追加新元素,當超過容量時應(yīng)該自動擴容。
  3. 向數(shù)組中指定位置添加新元素,需要考慮指定的下標是否越界,同樣也需要考慮擴容操作。
  4. 刪除末尾的元素,需要考慮縮小容量。
  5. 刪除指定位置元素,需要考慮指定的下標是否越界,同樣也需要考慮縮小容量。
  6. 修改特定位置的元素,需要考慮指定的下標是否越界。
  7. 以時間復雜度為O ( 1 ) O(1)O(1)獲取任意位置的元素,需要考慮指定的下標是否越界。

主要注意點:

  1. 擴容: 這里擴容2倍(ArrayList 是擴容 1.5 倍),擴容時新建一個2倍容量的新數(shù)組,然后將舊數(shù)組中的元素按順序拷貝到新數(shù)組。
  2. 縮容: 當數(shù)組中的元素個數(shù) <= 0.25 * 容量時,自動縮小容量為原來的一半,新建一個容量是原來容量一半的數(shù)組,然后將舊數(shù)組中的元素按順序拷貝到新數(shù)組。(ArrayList縮小為和當前元素個數(shù)一樣大)。
  3. 指定位置添加: 需要先將指定位置及后面所有的元素都向后移動一位,將指定位置空出來然后再插入。
  4. 指定位置刪除: 先將制定位置刪除,然后將后面的所有元素都向前移動一位。
  5. 容量大?。?需要指定容量的最大值,避免OOM的發(fā)生。最小值可以指定也可以不指定。

實現(xiàn)代碼

/**
 * 變長數(shù)組
 * */
public class ResizeableArray<E> {

    private static final int MIN_CAPACITY = 10;

    private static final int MAX_CAPACITY = Integer.MAX_VALUE - 8;

    // 當前實際數(shù)據(jù)大小
    private int size = 0;

    // 實際存放元素的數(shù)組,容量為 elements.length
    private Object[] elements;

    public ResizeableArray(){
        this(MIN_CAPACITY);
    }

    public ResizeableArray(int initCapacity){
        if(initCapacity < MIN_CAPACITY){
            initCapacity = MIN_CAPACITY;
        }else if(initCapacity > MAX_CAPACITY){
            initCapacity = MAX_CAPACITY;
        }
        this.elements = new Object[initCapacity];
    }

    // 數(shù)組的特性,根據(jù)下標獲取元素
    public E get(int index){
        this.checkIndex(index);
        return (E)elements[index];
    }

    // 添加一個元素到最后
    public void add(E element){
        if(size == elements.length){
            // 需要擴容
            this.expandCapacity();
        }
        elements[size++] = element;
    }

    // 添加一個元素到指定位置
    public void add(int index, E element){

        if(index == size){
            this.add(element);
            return;
        }
        this.checkIndex(index);
        if(size == elements.length){
            // 需要擴容
            this.expandCapacity();
        }
        // 需要先將index和之后的所有元素向后移動一位
        for(int i = size - 1; i >= index; i--){
            elements[i + 1] = elements[i];
        }
        elements[index] = element;
        size++;

    }

    // 設(shè)置下標為index的元素
    private void set(int index, E element){
        this.checkIndex(index);
        elements[index] = element;
    }

    /**
     * 刪除下標為index的元素
     * 當 size <= 0.25 * capacity 的時候縮小容量
     */

    private void delete(int index){
        this.checkIndex(index);
        elements[index] = null;
        // 如果刪除的不是最后一個元素,需要將后續(xù)元素往前移動一位
        if(index < size - 1){
            for(int i = index + 1; i < size; i++){
                elements[i - 1] = elements[i];
            }
        }
        size--;
        if(size <= 0.25 * elements.length){
            this.reduceCapacity();
        }
    }

    private void deleteLast(){
        this.delete(size - 1);
    }

    private void checkIndex(int index){
        if(index < 0 || index >= size){
            throw new IndexOutOfBoundsException(String.format("Out of bounds at: %s, size is: %d", index, size));
        }
    }

    private void expandCapacity(){
        if(MAX_CAPACITY == elements.length){
            // 容量達到最大限制,無法擴容。
            throw new RuntimeException("The capacity has reached its maximum limit and cannot be expanded.");
        }
        int newCapacity = Math.min(elements.length << 1, MAX_CAPACITY);
        Object[] newElements = new Object[newCapacity];
        System.arraycopy(elements, 0, newElements, 0, size);
        elements = newElements;
    }

    private void reduceCapacity(){
        if(elements.length == MIN_CAPACITY){
            return;
        }
        int newCapacity = Math.max(elements.length >> 1, MIN_CAPACITY);
        Object[] newElements = new Object[newCapacity];
        System.arraycopy(elements, 0, newElements, 0, size);
        elements = newElements;
    }



    public static void main(String[] args){
        ResizeableArray<Integer> resizeableArray = new ResizeableArray<>();
        System.out.printf("初始化后,size為: %d \n", resizeableArray.size);
        System.out.printf("初始化后,capacity為: %d \n", resizeableArray.elements.length);
        System.out.println();

        for(int i = 0; i < 20; i++){
            resizeableArray.add(i);
        }

        System.out.printf("添加20個元素后,size為: %d \n", resizeableArray.size);
        System.out.printf("添加20個元素后,capacity為: %d \n", resizeableArray.elements.length);
        System.out.printf("添加20個元素后,第5個元素是: %d \n", resizeableArray.get(4));
        System.out.println();

        resizeableArray.delete(4);

        System.out.printf("刪除第五個元素后,size為: %d \n", resizeableArray.size);
        System.out.printf("刪除第五個元素后,capacity為: %d \n", resizeableArray.elements.length);
        System.out.printf("刪除第五個元素后,第5個元素是: %d\n", resizeableArray.get(4));
        System.out.println();

        resizeableArray.add(4, 100);
        System.out.printf("在第五個位置插入元素后,size為: %d \n", resizeableArray.size);
        System.out.printf("在第五個位置插入元素后,capacity為: %d \n", resizeableArray.elements.length);
        System.out.printf("在第五個位置插入元素后,第5個元素是: %d\n", resizeableArray.get(4));
        System.out.println();

        for(int i = 0; i < 15; i++){
            resizeableArray.deleteLast();
        }
        System.out.printf("刪除后面15個元素后,size為: %d \n", resizeableArray.size);
        System.out.printf("刪除后面15個元素后,capacity為: %d \n", resizeableArray.elements.length);
        System.out.printf("刪除后面15個元素后,第5個元素是: %d\n", resizeableArray.get(4));
        System.out.println();

        resizeableArray.set(4, 200);
        System.out.printf("修改第五個元素后,當前size為: %d \n", resizeableArray.size);
        System.out.printf("修改第五個元素后,capacity為: %d \n", resizeableArray.elements.length);
        System.out.printf("修改第五個元素后,第5個元素是: %d\n", resizeableArray.get(4));

    }
}

測試結(jié)果

由執(zhí)行結(jié)果可知:

  • 初始化后默認容量為10
  • 添加元素超過10個后會自動擴容。
  • 刪除一個元素后,size會減1,后面元素會自動向前移動一位。
  • 插入一個新元素后,size會加1,后續(xù)元素后移一位。
  • 刪除到只有0.25 * 容量個元素后,會自動縮小容量。

總結(jié)

到此這篇關(guān)于Java自定義一個變長數(shù)組的思路與代碼的文章就介紹到這了,更多相關(guān)Java自定義變長數(shù)組內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java基礎(chǔ)學習之Swing事件監(jiān)聽

    Java基礎(chǔ)學習之Swing事件監(jiān)聽

    今天學習java的Swing庫,創(chuàng)建桌面應(yīng)用的時候,突然發(fā)現(xiàn)有些按鈕需要特定的功能響應(yīng),故來研究一番Swing的事件監(jiān)聽,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-05-05
  • Java多線程ThreadPoolExecutor詳解

    Java多線程ThreadPoolExecutor詳解

    這篇文章主要介紹了Java多線程ThreadPoolExecutor詳解,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • mybatis多對多關(guān)聯(lián)實戰(zhàn)教程(推薦)

    mybatis多對多關(guān)聯(lián)實戰(zhàn)教程(推薦)

    下面小編就為大家?guī)硪黄猰ybatis多對多關(guān)聯(lián)實戰(zhàn)教程(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • 基于Eclipce配置Spring Boot過程圖解

    基于Eclipce配置Spring Boot過程圖解

    這篇文章主要介紹了基于Eclipce配置Spring Boot過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • 關(guān)于java編譯過程中的bug說明

    關(guān)于java編譯過程中的bug說明

    本篇文章是對java編譯過程中的bug進行了詳細的說明介紹,需要的朋友參考下
    2013-05-05
  • java?poi?讀取單元格null或者空字符串方式

    java?poi?讀取單元格null或者空字符串方式

    這篇文章主要介紹了java?poi?讀取單元格null或者空字符串方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java操作PDF文件方法之轉(zhuǎn)換、合成、切分

    java操作PDF文件方法之轉(zhuǎn)換、合成、切分

    最近需要做?個把多個pdf報告合并成?個以?便預覽的需求,下面這篇文章主要給大家介紹了關(guān)于java操作PDF文件方法之轉(zhuǎn)換、合成、切分的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-01-01
  • MyBatis攔截器動態(tài)替換表名的方法詳解

    MyBatis攔截器動態(tài)替換表名的方法詳解

    因為我們持久層框架更多地使用MyBatis,那我們就借助于MyBatis的攔截器來完成我們的功能,這篇文章主要給大家介紹了關(guān)于MyBatis攔截器動態(tài)替換表名的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • springboot?集成easy-captcha實現(xiàn)圖像驗證碼顯示和登錄

    springboot?集成easy-captcha實現(xiàn)圖像驗證碼顯示和登錄

    本文主要介紹了springboot?集成easy-captcha實現(xiàn)圖像驗證碼顯示和登錄,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • 使用Java實現(xiàn)在Excel中添加動態(tài)數(shù)組公式

    使用Java實現(xiàn)在Excel中添加動態(tài)數(shù)組公式

    動態(tài)數(shù)組公式是?Excel?引入的一項重要功能,它允許用戶從單個單元格中的公式返回多個結(jié)果值,并將這些值自動填充到與公式單元格相鄰的單元格中,本文主要介紹了如何使用Java實現(xiàn)在Excel中添加動態(tài)數(shù)組公式,x需要的可以參考下
    2023-12-12

最新評論