一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java 動態數組的實現示例

Java 動態數組的實現示例

2021-12-07 13:07Pizzerias Java教程

Java動態數組是一種可以任意伸縮數組長度的對象,本文主要介紹了Java 動態數組的實現示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

 

靜態數組

Java中最基本的數組大家肯定不會陌生:

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

通過循環把元素放入指定的位置中,類似于這樣:

Java 動態數組的實現示例

這是一個靜態數組,因為我們在第一步初始化的時候就已經固定了它的長度,后面再也無法改變。所以,由于有這個限制,靜態數組不適用于那些不確定儲存多少數據的場景。
但是如果數組滿了,能否再新建一個更長一些的數組,把原數組這些元素再轉移到新數組中呢?這樣一來,數組就可以繼續使用了。按照這個思路,我們就可以創建基于靜態數組的動態數組。

 

動態數組的實現原理

“動態”主要體現在以下幾方面:

 

1.添加元素

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

Java 動態數組的實現示例

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

 

2.刪除元素

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

Java 動態數組的實現示例

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

 

3.數組擴容

數組一旦裝滿元素,可觸發數組擴容,即新建一個更長的數組,將原數組元素轉移到新數組中,并將引用指向新數組,完成數組的變更;

Java 動態數組的實現示例

 

4.數組縮減

如果數組元素相對總容量來說過少(例如數組元素個數小于數組容量的1/4),便可觸發數組縮減,即新建一個更短的數組,并轉移元素至新數組。

Java 動態數組的實現示例

代碼實現

以下通過新建一個 Array 類,依次實現這幾個重要功能:

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

接下來我們測試一下這個數組的使用情況:

public static void main(String[] args) {
        // 添加10個元素
        Array<Integer> arr = new Array<>();
        for (int i = 0; i < 10; i++)
            arr.add(i, i);
        // 查看數組當前狀態
        System.out.println(arr);
        // 繼續添加元素,觀察是否擴容
        arr.add(arr.size, 7);
        System.out.println(arr);
 
        // 再刪除6個元素,觀察是否縮減
        for (int i = 0; i < 6; i++) {
            System.out.println("元素" + arr.removeFirst() + "已被刪除!");
        }
        System.out.println(arr);
    }
 
/*
輸出結果:
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]
*/

可以看到,當數組滿員后,繼續添加元素可以成功觸發數組擴容;而當數組元素過少時,也會觸發縮減。
再實現幾個常用方法來完善我們的動態數組類:

    // 獲取數組長度
    public int getSize() {
        return size;
    }
 
    // 獲取數組總容量
    public int getCapacity() {
        return data.length;
    }
 
    // 判斷數組是否為空
    public boolean isEmpty() {
        return getSize() == 0;
    }
 
    // 查找指定元素在數組中的位置
    public int search(E element) {
        for (int i = 0; i < getSize(); i++) {
            if (data[i].equals(element)) {
                return i;
            }
        }
        // -1表示未找到
        return -1;
    }
 
    // 判斷指定元素是否在數組中
    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);
    }
 
    // 設置指定位置的元素值
    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;
    }
 
    /**
     * 按照元素值刪除
     * 只刪除數組中第一個元素值與指定值相等的元素
     * @param element 指定元素值
     */
    public boolean removeElement(E element) {
        int index = search(element);
        if (index != -1) {
            remove(index);
            return true;
        }
        return false;
    }
 
    /**
     * 按照元素值刪除
     * 刪除數組中所有值與指定值相等的元素
     *
     * @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;
    }

從外部調用者的角度,無法覺察到其中的數組變更操作,感覺就是一個動態數組,但是由于擴容和縮減操作均需要新建數組,并且遍歷原數組,會導致過多的開銷,所以從性能上來說,并不是好的解決方案。后面我們將學習更加高效的數據結構。

到此這篇關于Java 動態數組的實現示例的文章就介紹到這了,更多相關Java 動態數組內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://www.cnblogs.com/dev-liu/p/15150356.html

延伸 · 閱讀

精彩推薦
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
主站蜘蛛池模板: www视频在线免费观看 | 2015小明台湾永久区域免费 | 美女福利网站 | 91大神第九部红酒气质女 | 大又大又粗又爽女人毛片 | 国产精品视频网 | 成人黄色a级片 | 日韩欧美国产免费看清风阁 | 欧洲喷浆乌克兰 | 欧美一级片在线免费观看 | 国内视频一区二区三区 | www.福利| 色综合中文字幕在线亚洲 | 亚洲欧洲日产国码无码av | 三上悠亚精品专区久久 | 国语自产拍在线播放不卡 | 网址在线观看你懂我意思吧免费的 | 美日毛片 | 色婷婷久久综合中文久久一本` | 日本视频观看 | avtt在线观看 | 日韩亚洲人成在线综合 | 五月天久久久 | 欧式午夜理伦三级在线观看 | 香蕉视频久久 | 欧美视频黑鬼大战白妞 | 爆操 | 99久久九九 | 国产成人啪精品午夜在线观看 | 2020国产精品视频免费 | 亚洲精品一区二区三区在线播放 | 调教女帝| 极品在线| 日本色播| 三体动漫在线观看免费完整版2022 | 成年人免费在线看的惊悚动作片 | 午夜看片a福利在线观看 | 日本高清在线播放一区二区三区 | 国产香蕉一区二区在线网站 | a在线观看欧美在线观看 | 日本在线播放 |