最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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)文章

  • spring boot配置多個(gè)請(qǐng)求服務(wù)代理的完整步驟

    spring boot配置多個(gè)請(qǐng)求服務(wù)代理的完整步驟

    這篇文章主要給大家介紹了關(guān)于spring boot配置多個(gè)請(qǐng)求服務(wù)代理的完整步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • springcloud-feign調(diào)用報(bào)錯(cuò)問(wèn)題

    springcloud-feign調(diào)用報(bào)錯(cuò)問(wèn)題

    這篇文章主要介紹了springcloud-feign調(diào)用報(bào)錯(cuò)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Spring Data Jpa 復(fù)合主鍵的實(shí)現(xiàn)

    Spring Data Jpa 復(fù)合主鍵的實(shí)現(xiàn)

    這篇文章主要介紹了Spring Data Jpa 復(fù)合主鍵的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • SpringBoot實(shí)現(xiàn)文件上傳下載實(shí)時(shí)進(jìn)度條功能(附源碼)

    SpringBoot實(shí)現(xiàn)文件上傳下載實(shí)時(shí)進(jìn)度條功能(附源碼)

    這篇文章主要為大家詳細(xì)介紹了SpringBoot如何實(shí)現(xiàn)文件上傳下載實(shí)時(shí)進(jìn)度條功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下
    2022-10-10
  • 詳解關(guān)于Windows10 Java環(huán)境變量配置問(wèn)題的解決辦法

    詳解關(guān)于Windows10 Java環(huán)境變量配置問(wèn)題的解決辦法

    這篇文章主要介紹了關(guān)于Windows10 Java環(huán)境變量配置問(wèn)題的解決辦法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • java迷宮算法的理解(遞歸分割,遞歸回溯,深搜,廣搜)

    java迷宮算法的理解(遞歸分割,遞歸回溯,深搜,廣搜)

    本文主要使用的算法(自動(dòng)生成地圖:遞歸分割法、遞歸回溯法;尋找路徑:深度優(yōu)先、廣度優(yōu)先算法),非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2021-06-06
  • MyBatis實(shí)現(xiàn)多表聯(lián)查的詳細(xì)代碼

    MyBatis實(shí)現(xiàn)多表聯(lián)查的詳細(xì)代碼

    這篇文章主要介紹了MyBatis如何實(shí)現(xiàn)多表聯(lián)查,通過(guò)實(shí)例代碼給大家介紹使用映射配置文件實(shí)現(xiàn)多表聯(lián)查,使用注解的方式實(shí)現(xiàn)多表聯(lián)查,需要的朋友可以參考下
    2022-08-08
  • Java實(shí)現(xiàn)Dijkstra算法的示例代碼

    Java實(shí)現(xiàn)Dijkstra算法的示例代碼

    Dijkstra(迪杰斯特拉)算法是典型的單源最短路徑算法,用于計(jì)算一個(gè)節(jié)點(diǎn)到其他所有節(jié)點(diǎn)的最短路徑。本文主要介紹了實(shí)現(xiàn)這一算法的Java代碼,需要的可以參考一下
    2022-07-07
  • Spring Bean創(chuàng)建和循環(huán)依賴

    Spring Bean創(chuàng)建和循環(huán)依賴

    這篇文章主要介紹了Spring Bean創(chuàng)建和循環(huán)依賴,講述了Spring容器中?Bean?的創(chuàng)建過(guò)程已經(jīng)主要的方法,另外也著重分析了循環(huán)依賴的問(wèn)題,需要的小伙伴可以參考一下
    2022-05-05
  • java中建立0-10m的消息(字符串)實(shí)現(xiàn)方法

    java中建立0-10m的消息(字符串)實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇java中建立0-10m的消息(字符串)實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05

最新評(píng)論

武隆县| 姚安县| 孝感市| 永德县| 博罗县| 宁武县| 罗源县| 彰化县| 泌阳县| 胶州市| 罗山县| 罗源县| 呼和浩特市| 景德镇市| 伊吾县| 通化县| 乌审旗| 宁武县| 和田县| 阿瓦提县| 太仆寺旗| 河津市| 阿拉尔市| 晋州市| 普定县| 浦江县| 塔城市| 蓝田县| 阿巴嘎旗| 红河县| 西丰县| 永州市| 天门市| 抚州市| 岚皋县| 保靖县| 浦北县| 厦门市| 开平市| 洛南县| 静海县|