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

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

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

前言

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

思路分析

主要功能點(diǎn):

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

主要注意點(diǎn):

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

實(shí)現(xiàn)代碼

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

    private static final int MIN_CAPACITY = 10;

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

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

    // 實(shí)際存放元素的數(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ù)下標(biāo)獲取元素
    public E get(int index){
        this.checkIndex(index);
        return (E)elements[index];
    }

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

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

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

    }

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

    /**
     * 刪除下標(biāo)為index的元素
     * 當(dāng) size <= 0.25 * capacity 的時(shí)候縮小容量
     */

    private void delete(int index){
        this.checkIndex(index);
        elements[index] = null;
        // 如果刪除的不是最后一個(gè)元素,需要將后續(xù)元素往前移動(dòng)一位
        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){
            // 容量達(dá)到最大限制,無(wú)法擴(kuò)容。
            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個(gè)元素后,size為: %d \n", resizeableArray.size);
        System.out.printf("添加20個(gè)元素后,capacity為: %d \n", resizeableArray.elements.length);
        System.out.printf("添加20個(gè)元素后,第5個(gè)元素是: %d \n", resizeableArray.get(4));
        System.out.println();

        resizeableArray.delete(4);

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

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

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

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

    }
}

測(cè)試結(jié)果

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

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

總結(jié)

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

相關(guān)文章

  • Java基礎(chǔ)學(xué)習(xí)之Swing事件監(jiān)聽(tīng)

    Java基礎(chǔ)學(xué)習(xí)之Swing事件監(jiān)聽(tīng)

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

    Java多線程ThreadPoolExecutor詳解

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

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

    下面小編就為大家?guī)?lái)一篇mybatis多對(duì)多關(guān)聯(lián)實(shí)戰(zhàn)教程(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • 基于Eclipce配置Spring Boot過(guò)程圖解

    基于Eclipce配置Spring Boot過(guò)程圖解

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

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

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

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

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

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

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

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

    因?yàn)槲覀兂志脤涌蚣芨嗟厥褂肕yBatis,那我們就借助于MyBatis的攔截器來(lái)完成我們的功能,這篇文章主要給大家介紹了關(guān)于MyBatis攔截器動(dòng)態(tài)替換表名的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • springboot?集成easy-captcha實(shí)現(xiàn)圖像驗(yàn)證碼顯示和登錄

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

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

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

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

最新評(píng)論