簡體   English   中英

為 Map/Associative Array 數據結構實現 put(或 add)方法

[英]Implementing a put (or add) method for a Map/Associative Array Data Structure

我得到了一個 Map 數據結構,其中 K 代表鍵,V 代表值。

現在我被要求實現經典的put(K key, V value)方法,該方法隨集合一起提供。 該方法是預先實現的,並從所使用的接口覆蓋一個:

@Override
    public void put(K key, V value) {
        for (int i = 0; i <= this.entries.length; i++) {
            if (this.entries[i] == null || this.entries[i].getKey().equals(key)) {
                this.entries[i] = new Entry<K, V>(key, value);
                return;
            } else {
                this.entries = GenericArrayHelper.copyArrayWithIncreasedSize(this.entries, (this.entries.length) * 2);
                /*  replace [...]
                this.entries[...] = new Entry<K, V>(key, value);
                 */
            }
        }
    }

除了被注釋掉的部分,我需要用陣列的正確 position 替換 [...]。 即:

如果 map 中索引 i 處的 Entry<K,V> 是 null,或者索引 i 處的條目的鍵等於傳遞過來的鍵,則將該條目替換為包含傳遞的鍵和值的新條目,並完成該方法。

如果找不到這樣的Entry<K,V>,則應完整復制調用該方法的map(形式為entry<K,V>[ ]的數組),其數組大小應為加倍(使用輔助方法GenericArrayHelper.copyArrayWithIncreasedSize )。 隨后,在復制和調整大小的數組的第一個空槽處,使用傳遞的鍵和值放入一個新條目。

這就是產生混亂的地方。 我試圖用各種索引替換 [...],但從未得到令人滿意的結果。

當我嘗試輸入這幾個條目時, putInside是 Map:

putInside.put("sizeInMB", 42);
putInside.put("version", 4);
putInside.put("yearOfRelease", 2015);

打印時(使用單獨的 toString 方法“字符串化”),我將得到以下結果:

yearOfRelease : 2015
sizeInMB : 42
version : 4
yearOfRelease : 2015
sizeInMB : 42
version : 4

但是當我說,使用entry.length-1的數組索引來表示 [...],這是我經過數小時的嘗試后最接近的,並觀察調試器,它看起來很糟糕:

在此處輸入圖像描述

前三個條目是正確的,但其他三個被混搭了......當我打印整個內容時,我只得到第一個樹條目的 output,因為其他三個似乎被完全忽略(也許是因為更大for 循環中的 arrays 僅在循環本身中定義?)

我的問題是:我如何為索引 [...] 定義一個合適的替代品,或者,也許也是為了更好地理解:為什么我們首先需要將數組的大小加倍? 我以前從未實現過任何 Java 集合數據結構,也沒有在的大學采用數據結構 class ......

任何形式的幫助都會非常感激!

編輯:為了讓事情更清楚,這里是 toString 方法:

public static void toString(Map<String, Integer> print) {
        for(String key : print.keysAsSet()){
                System.out.println(key + ": " + print.getValueFor(key));
        }
    }

使用keysAsSet()返回 Map 的 HashSet,其中僅包含鍵,但不包含值。

public Set<K> keysAsSet() {
        HashSet<K> current = new HashSet<>();
        for(Entry<K,V> entry : entries){
            if(entry != null) {
                current.add(entry.getKey());
            }
        }
        return current;
    }

代碼與描述不符。 也就是說,您正在調整循環內的數組大小,除非entries中的第一個元素是命中(即它是null或它等於鍵)。

您需要在循環之后調整數組大小(加上修復循環條件檢查):

@Override
public void put(K key, V value) {
    int oldLength = this.entries.length;
    for (int i = 0; i < oldLength; i++) {
        if (this.entries[i] == null || this.entries[i].getKey().equals(key)) {
            this.entries[i] = new Entry<K, V>(key, value);
            return;
        }
    }
    this.entries = GenericArrayHelper.copyArrayWithIncreasedSize(this.entries, oldLength * 2);
    this.entries[oldLength] = new Entry<K, V>(key, value);
}

…我假設您知道這是一個非常低效的 map 實現:每次搜索和插入都需要O ( n ) 次嘗試。 實際上,您可以使用 hash 表或某種搜索樹來加速插入和查找。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM