简体   繁体   English

为 Map/Associative Array 数据结构实现 put(或 add)方法

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

I am given a Map Data Structure with the Generic Types (K,V) where the K represents the key, and the V represents the value.我得到了一个 Map 数据结构,其中 K 代表键,V 代表值。

Now I am asked to implement the classic put(K key, V value) method, which comes along with the collection.现在我被要求实现经典的put(K key, V value)方法,该方法随集合一起提供。 The method is pre-implemented, and overrides the one from an interface which is used:该方法是预先实现的,并从所使用的接口覆盖一个:

@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);
                 */
            }
        }
    }

With the exception of the part that's commented out, where I would need to replace the [...] with the correct position of the array.除了被注释掉的部分,我需要用阵列的正确 position 替换 [...]。 Namely:即:

If an Entry<K,V> at index i in the map is null, or the key of the entry at index i equals the key that was passed over, replace the entry with a new entry containing the key and value that are passed, and finish the method.如果 map 中索引 i 处的 Entry<K,V> 是 null,或者索引 i 处的条目的键等于传递过来的键,则将该条目替换为包含传递的键和值的新条目,并完成该方法。

If such an Entry<K,V> cannot be found, the map (which is an array of the form entries<K,V>[ ]) which the method is called on, shall be copied in full and its array size shall be doubled (with the aiding method GenericArrayHelper.copyArrayWithIncreasedSize ).如果找不到这样的Entry<K,V>,则应完整复制调用该方法的map(形式为entry<K,V>[ ]的数组),其数组大小应为加倍(使用辅助方法GenericArrayHelper.copyArrayWithIncreasedSize )。 Successively, at the very first vacant slot of the copied and resized array , put in a new Entry with the passed key and value.随后,在复制和调整大小的数组的第一个空槽处,使用传递的键和值放入一个新条目。

And this is where the confusion arose.这就是产生混乱的地方。 I have tried to replace [...] with all kinds of indices, but have never gotten a satisfactory result.我试图用各种索引替换 [...],但从未得到令人满意的结果。

When I try to put in these several entries, with putInside being a Map:当我尝试输入这几个条目时, putInside是 Map:

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

I shall get the following result, when printing ("stringified" with a separate toString method):打印时(使用单独的 toString 方法“字符串化”),我将得到以下结果:

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

but when I, say, use the array index of entries.length-1 for [...], which is the closest I got to after hours of trying, and watch the debugger, it looks abysmal:但是当我说,使用entry.length-1的数组索引来表示 [...],这是我经过数小时的尝试后最接近的,并观察调试器,它看起来很糟糕:

在此处输入图像描述

with the first three entries being correct, but the other three getting mashed up... and when I print the whole thing I merely get an output of the first tree entries, since the other three seem to be ignored completely (perhaps because the larger arrays in the for loop are merely defined in the loop itself?)前三个条目是正确的,但其他三个被混搭了......当我打印整个内容时,我只得到第一个树条目的 output,因为其他三个似乎被完全忽略(也许是因为更大for 循环中的 arrays 仅在循环本身中定义?)

My question is: How do I define a suitable replacement for the index [...], or, maybe also for better understanding: Why on earth would we need to double the size of the array first?我的问题是:我如何为索引 [...] 定义一个合适的替代品,或者,也许也是为了更好地理解:为什么我们首先需要将数组的大小加倍? I have never implemented any Java Collection data structure before, and also haven't taken the data structures class at my uni yet... How do I get to a "doubled" output?我以前从未实现过任何 Java 集合数据结构,也没有在的大学采用数据结构 class ......

Any form of help would be really really appreciated!任何形式的帮助都会非常感激!

EDIT: To make things clearer, here is the toString method:编辑:为了让事情更清楚,这里是 toString 方法:

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

with keysAsSet() returning a HashSet of the Map, which merely contains the keys, but not the values.使用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;
    }

The code doesn't match the description.代码与描述不符。 To wit, you are resizing the array inside the loop , unless the very first element in entries is a hit (ie it's null or it equals the key).也就是说,您正在调整循环内的数组大小,除非entries中的第一个元素是命中(即它是null或它等于键)。

You need to put the array resizing after the loop (plus fix the loop condition check):您需要在循环之后调整数组大小(加上修复循环条件检查):

@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);
}

… I assume you're aware that this is a very inefficient map implementation: each search and insertion take O ( n ) tries. …我假设您知道这是一个非常低效的 map 实现:每次搜索和插入都需要O ( n ) 次尝试。 In reality you'd either use a hash table or some sort of search tree to speed up insertion and lookup.实际上,您可以使用 hash 表或某种搜索树来加速插入和查找。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM