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

Java 動(dòng)態(tài)數(shù)組的實(shí)現(xiàn)示例

 更新時(shí)間:2021年08月27日 09:45:00   作者:Pizzerias  
Java動(dòng)態(tài)數(shù)組是一種可以任意伸縮數(shù)組長(zhǎng)度的對(duì)象,本文主要介紹了Java 動(dòng)態(tài)數(shù)組的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

靜態(tài)數(shù)組

Java中最基本的數(shù)組大家肯定不會(huì)陌生:

int[] array = new int[6];
for (int i = 0; i < array.length; i++){
    array[i] = 2 * i + 1;
}

通過(guò)循環(huán)把元素放入指定的位置中,類(lèi)似于這樣:


這是一個(gè)靜態(tài)數(shù)組,因?yàn)槲覀冊(cè)诘谝徊匠跏蓟臅r(shí)候就已經(jīng)固定了它的長(zhǎng)度,后面再也無(wú)法改變。所以,由于有這個(gè)限制,靜態(tài)數(shù)組不適用于那些不確定儲(chǔ)存多少數(shù)據(jù)的場(chǎng)景。
但是如果數(shù)組滿(mǎn)了,能否再新建一個(gè)更長(zhǎng)一些的數(shù)組,把原數(shù)組這些元素再轉(zhuǎn)移到新數(shù)組中呢?這樣一來(lái),數(shù)組就可以繼續(xù)使用了。按照這個(gè)思路,我們就可以創(chuàng)建基于靜態(tài)數(shù)組的動(dòng)態(tài)數(shù)組。

動(dòng)態(tài)數(shù)組的實(shí)現(xiàn)原理

“動(dòng)態(tài)”主要體現(xiàn)在以下幾方面:

1.添加元素

不局限于只在數(shù)組末尾添加,而是能夠隨意選擇索引位置(只要不超過(guò)數(shù)組長(zhǎng)度)。例如在索引為1處添加元素4:


從圖中可以看出,需要將index處及右側(cè)的元素依次向右移動(dòng)一個(gè)單位(從末位元素開(kāi)始),最后用新增元素覆蓋index處元素。

2.刪除元素

同添加元素,也可根據(jù)索引進(jìn)行選擇。例如刪除索引為0處的元素3:


刪除元素移動(dòng)元素的方向與添加元素正好相反,從index處開(kāi)始,直接使用后一位元素覆蓋前一位元素,最后將末位元素置為null。

3.數(shù)組擴(kuò)容

數(shù)組一旦裝滿(mǎn)元素,可觸發(fā)數(shù)組擴(kuò)容,即新建一個(gè)更長(zhǎng)的數(shù)組,將原數(shù)組元素轉(zhuǎn)移到新數(shù)組中,并將引用指向新數(shù)組,完成數(shù)組的變更;

4.數(shù)組縮減

如果數(shù)組元素相對(duì)總?cè)萘縼?lái)說(shuō)過(guò)少(例如數(shù)組元素個(gè)數(shù)小于數(shù)組容量的1/4),便可觸發(fā)數(shù)組縮減,即新建一個(gè)更短的數(shù)組,并轉(zhuǎn)移元素至新數(shù)組。

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

以下通過(guò)新建一個(gè) Array 類(lèi),依次實(shí)現(xiàn)這幾個(gè)重要功能:

public class Array<E> {
    private E[] data;       // 使用靜態(tài)數(shù)組存放數(shù)組元素
    private int size;       // 記錄數(shù)組元素?cái)?shù)量
 
    public Array(int capacity) {
        this.data = (E[]) new Object[capacity];
        this.size = 0;
    }
 
    public Array() {
        this(10);   // 默認(rèn)capacity為10
    }
 
    // 數(shù)組擴(kuò)容/縮減
    public void resize(int newCapacity) {
        // 新數(shù)組長(zhǎng)度必須大于0
        if (newCapacity < 0) throw new IllegalArgumentException("capacity must > 0!");
        // 創(chuàng)建新數(shù)組
        E[] newData = (E[]) new Object[newCapacity];
        // 將原數(shù)組元素放入新數(shù)組中
        for (int i = 0; i < size; i++) {
            newData[i] = data[i];
        }
        // 將引用指向新數(shù)組
        data = newData;
    }
 
    /**
     * 在指定位置添加元素
     * 指定位置處的元素需要向右側(cè)移動(dòng)一個(gè)單位
     * @param index   索引
     * @param element 要添加的元素
     */
    public void add(int index, E element) {
        if (index < 0 || index > size) throw new IllegalArgumentException("Illegal index, index must > 0 and <= size!");
        // 數(shù)組滿(mǎn)員觸發(fā)擴(kuò)容
        if (size == data.length) {
            resize(2 * data.length);  // 擴(kuò)容為原數(shù)組的2倍
        }
        // 從尾部開(kāi)始,向右移動(dòng)元素,直到index
        for (int i = size - 1; i >= index; i--) {
            data[i + 1] = data[i];
        }
        // 添加元素
        data[index] = element;
        size++;
    }
 
    // 數(shù)組頭部添加元素
    public void addFirst(E element) {
        add(0, element);
    }
 
    // 數(shù)組尾部添加元素
    public void addLast(E element) {
        add(size, element);
    }
 
    /**
     * 刪除指定位置元素
     * 通過(guò)向左移動(dòng)一位,覆蓋指定位置處的元素,實(shí)現(xiàn)刪除元素(data[size - 1] = null)
     * @param index 索引
     */
    public E remove(int index) {
        if (index < 0 || index > size) throw new IllegalArgumentException("Illegal index, index must > 0 and < size!");
        // 數(shù)組長(zhǎng)度為0時(shí)拋出異常
        if (size == 0) throw new IllegalArgumentException("Empty array!");
        E removedElement = data[index];
        // 向左移動(dòng)元素
        for (int i = index; i < size - 1; i++) {
            data[i] = data[i + 1];
        }
        // 將尾部空閑出的位置置為空,釋放資源
        data[size - 1] = null;
        size--;
        // size過(guò)小觸發(fā)數(shù)組縮減
        if (size == data.length / 4 && data.length / 2 != 0) resize(data.length / 2);
        return removedElement;
    }
 
    // 刪除頭部元素
    public E removeFirst() {
        return remove(0);
    }
 
    // 刪除尾部元素
    public E removeLast() {
        return remove(size - 1);
    }
 
    // 重寫(xiě)Override方法,自定義數(shù)組顯示格式
    @Override
    public String toString() {
        StringBuilder str = new StringBuilder();
        // 顯示數(shù)組的整體情況(長(zhǎng)度、總?cè)萘?
        str.append(String.format("Array: size = %d, capacity = %d\n[", size, data.length));
        // 循環(huán)添加數(shù)組元素至str
        for (int i = 0; i < size; i++) {
            str.append(data[i]);
            if (i < size - 1) str.append(", ");
        }
        str.append("]");
        return str.toString();
    }
}

接下來(lái)我們測(cè)試一下這個(gè)數(shù)組的使用情況:

public static void main(String[] args) {
        // 添加10個(gè)元素
        Array<Integer> arr = new Array<>();
        for (int i = 0; i < 10; i++)
            arr.add(i, i);
        // 查看數(shù)組當(dāng)前狀態(tài)
        System.out.println(arr);
        // 繼續(xù)添加元素,觀察是否擴(kuò)容
        arr.add(arr.size, 7);
        System.out.println(arr);
 
        // 再刪除6個(gè)元素,觀察是否縮減
        for (int i = 0; i < 6; i++) {
            System.out.println("元素" + arr.removeFirst() + "已被刪除!");
        }
        System.out.println(arr);
    }
 
/*
輸出結(jié)果:
Array: size = 10, capacity = 10
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Array: size = 11, capacity = 20
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 7]
元素0已被刪除!
元素1已被刪除!
元素2已被刪除!
元素3已被刪除!
元素4已被刪除!
元素5已被刪除!
Array: size = 5, capacity = 10
[6, 7, 8, 9, 7]
*/

可以看到,當(dāng)數(shù)組滿(mǎn)員后,繼續(xù)添加元素可以成功觸發(fā)數(shù)組擴(kuò)容;而當(dāng)數(shù)組元素過(guò)少時(shí),也會(huì)觸發(fā)縮減。
再實(shí)現(xiàn)幾個(gè)常用方法來(lái)完善我們的動(dòng)態(tài)數(shù)組類(lèi):

    // 獲取數(shù)組長(zhǎng)度
    public int getSize() {
        return size;
    }
 
    // 獲取數(shù)組總?cè)萘?
    public int getCapacity() {
        return data.length;
    }
 
    // 判斷數(shù)組是否為空
    public boolean isEmpty() {
        return getSize() == 0;
    }
 
    // 查找指定元素在數(shù)組中的位置
    public int search(E element) {
        for (int i = 0; i < getSize(); i++) {
            if (data[i].equals(element)) {
                return i;
            }
        }
        // -1表示未找到
        return -1;
    }
 
    // 判斷指定元素是否在數(shù)組中
    public boolean contains(E element) {
        return search(element) != -1;
    }
 
    // 按照索引查找元素值
    public E get(int index) {
        if (index < 0 || index > size) throw new IllegalArgumentException("Illegal index, index must > 0 and < size!");
        return data[index];
    }
 
    // 查找頭部元素
    public E getFirst() {
        return get(0);
    }
 
    // 查找尾部元素
    public E getLast() {
        return get(getSize() - 1);
    }
 
    // 設(shè)置指定位置的元素值
    public void set(int index, E element) {
        if (index < 0 || index > size) throw new IllegalArgumentException("Illegal index, index must > 0 and < size!");
        data[index] = element;
    }
 
    /**
     * 按照元素值刪除
     * 只刪除數(shù)組中第一個(gè)元素值與指定值相等的元素
     * @param element 指定元素值
     */
    public boolean removeElement(E element) {
        int index = search(element);
        if (index != -1) {
            remove(index);
            return true;
        }
        return false;
    }
 
    /**
     * 按照元素值刪除
     * 刪除數(shù)組中所有值與指定值相等的元素
     *
     * @param element 指定元素值
     */
    public boolean removeElementAll(E element) {
        boolean isRemoved = false;
        int i = getSize() - 1;
        while (i >= 0) {
            if (data[i].equals(element)) {
                remove(i);
                isRemoved = true;
            }
            i--;
        }
        return isRemoved;
    }

從外部調(diào)用者的角度,無(wú)法覺(jué)察到其中的數(shù)組變更操作,感覺(jué)就是一個(gè)動(dòng)態(tài)數(shù)組,但是由于擴(kuò)容和縮減操作均需要新建數(shù)組,并且遍歷原數(shù)組,會(huì)導(dǎo)致過(guò)多的開(kāi)銷(xiāo),所以從性能上來(lái)說(shuō),并不是好的解決方案。后面我們將學(xué)習(xí)更加高效的數(shù)據(jù)結(jié)構(gòu)。

到此這篇關(guān)于Java 動(dòng)態(tài)數(shù)組的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Java 動(dòng)態(tài)數(shù)組內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot中實(shí)現(xiàn)數(shù)據(jù)字典的示例代碼

    SpringBoot中實(shí)現(xiàn)數(shù)據(jù)字典的示例代碼

    這篇文章主要介紹了SpringBoot中實(shí)現(xiàn)數(shù)據(jù)字典的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Java算法之?dāng)?shù)組冒泡排序代碼實(shí)例講解

    Java算法之?dāng)?shù)組冒泡排序代碼實(shí)例講解

    這篇文章主要介紹了Java算法之?dāng)?shù)組冒泡排序代碼實(shí)例講解,文中用代碼舉例講解的很清晰,有感興趣的同學(xué)可以研究下
    2021-03-03
  • 詳解SpringBoot啟動(dòng)代碼和自動(dòng)裝配源碼分析

    詳解SpringBoot啟動(dòng)代碼和自動(dòng)裝配源碼分析

    這篇文章主要介紹了SpringBoot啟動(dòng)代碼和自動(dòng)裝配源碼分析,使用SpringBoot很簡(jiǎn)單,在主類(lèi)中添加一個(gè)@SpringBootApplication,以及調(diào)用SpringApplication.run()并傳入主類(lèi),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • Java內(nèi)存模型知識(shí)匯總

    Java內(nèi)存模型知識(shí)匯總

    本文中,有很多定義和說(shuō)法,都是筆者自己理解后定義出來(lái)的。希望能夠讓讀者可以對(duì)Java內(nèi)存模型有更加清晰的認(rèn)識(shí)。當(dāng)然,如有偏頗,歡迎指正。
    2018-09-09
  • Java中為什么start方法不能重復(fù)調(diào)用而run方法可以?

    Java中為什么start方法不能重復(fù)調(diào)用而run方法可以?

    這篇文章主要介紹了Java中為什么start方法不能重復(fù)調(diào)用而run方法可以?帶著疑問(wèn)一起學(xué)習(xí)下面文章的詳細(xì)內(nèi)容吧
    2022-05-05
  • Spring循環(huán)依賴(lài)的三種方式(推薦)

    Spring循環(huán)依賴(lài)的三種方式(推薦)

    本篇文章主要介紹了Spring循環(huán)依賴(lài)的三種方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • SpringBoot 如何編寫(xiě)配置文件

    SpringBoot 如何編寫(xiě)配置文件

    這篇文章主要介紹了SpringBoot 編寫(xiě)配置文件的兩種方法,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-11-11
  • Java中Comparator升序降序的具體使用

    Java中Comparator升序降序的具體使用

    本文主要介紹了Java中Comparator升序降序的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • JAVA最容易忽視的數(shù)據(jù)類(lèi)型之枚舉詳解

    JAVA最容易忽視的數(shù)據(jù)類(lèi)型之枚舉詳解

    這篇文章主要給大家介紹了關(guān)于JAVA最容易忽視的數(shù)據(jù)類(lèi)型之枚舉的相關(guān)資料,Java中的枚舉類(lèi)型是一種特殊的類(lèi)型,它允許程序員定義一個(gè)固定的值集合,并為每個(gè)值分配一個(gè)名稱(chēng),枚舉類(lèi)型提供了一種簡(jiǎn)單、安全和可讀性強(qiáng)的方式來(lái)表示一組相關(guān)的常量,需要的朋友可以參考下
    2023-10-10
  • 使用dom4j遞歸解析節(jié)點(diǎn)內(nèi)還含有多個(gè)節(jié)點(diǎn)的xml

    使用dom4j遞歸解析節(jié)點(diǎn)內(nèi)還含有多個(gè)節(jié)點(diǎn)的xml

    這篇文章主要介紹了使用dom4j遞歸解析節(jié)點(diǎn)內(nèi)還含有多個(gè)節(jié)點(diǎn)的xml,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評(píng)論

偃师市| 石柱| 太仓市| 河津市| 原阳县| 通海县| 江源县| 汾西县| 大丰市| 冷水江市| 高阳县| 章丘市| 阿荣旗| 密山市| 麻栗坡县| 桃源县| 乡城县| 新田县| 南澳县| 高安市| 廊坊市| 青铜峡市| 秦安县| 双流县| 沁水县| 宁晋县| 桃源县| 广平县| 綦江县| 南投县| 永和县| 南宫市| 长治市| 大理市| 元阳县| 日喀则市| 晴隆县| 康马县| 怀仁县| 海宁市| 大港区|