Java 为映射/关联数组数据结构实现put(或add)方法
我得到了一个带有泛型类型(K,V)的映射数据结构,其中K表示键,V表示值 现在,我被要求实现集合附带的经典put(K键,V值)方法。该方法是预实现的,并覆盖所使用接口中的方法:Java 为映射/关联数组数据结构实现put(或add)方法,java,arrays,dictionary,collections,Java,Arrays,Dictionary,Collections,我得到了一个带有泛型类型(K,V)的映射数据结构,其中K表示键,V表示值 现在,我被要求实现集合附带的经典put(K键,V值)方法。该方法是预实现的,并覆盖所使用接口中的方法: @Override public void put(K key, V value) { for (int i = 0; i <= this.entries.length; i++) { if (this.entries[i] == null || this.entri
@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);
*/
}
}
}
在打印时,我将得到以下结果(使用单独的toString方法(“stringized”):
但是,当我使用entries.length-1的数组索引表示[…]时,这是我经过几个小时的尝试后得到的最接近的索引,并且观察调试器时,它看起来非常糟糕:
前三个条目是正确的,但其他三个条目被混合在一起。。。当我打印整个内容时,我只得到第一个树条目的输出,因为其他三个条目似乎被完全忽略了(可能是因为for循环中较大的数组仅仅是在循环本身中定义的?)
我的问题是:我如何定义索引[…]的合适替代品,或者,为了更好地理解:究竟为什么我们需要首先将数组的大小增加一倍?我以前从未实现过任何Java集合数据结构,也没有在我的大学学习过data structures类如何实现“双倍”输出?
任何形式的帮助都将不胜感激
编辑:为了让事情更清楚,下面是toString方法:
yearOfRelease : 2015
sizeInMB : 42
version : 4
yearOfRelease : 2015
sizeInMB : 42
version : 4
public static void toString(Map<String, Integer> print) {
for(String key : print.keysAsSet()){
System.out.println(key + ": " + print.getValueFor(key));
}
}
publicstaticvoidtostring(地图打印){
for(字符串键:print.keysAsSet()){
System.out.println(key+”:“+print.getValueFor(key));
}
}
with keysAsSet()返回映射的哈希集,该哈希集仅包含键,而不包含值
public Set<K> keysAsSet() {
HashSet<K> current = new HashSet<>();
for(Entry<K,V> entry : entries){
if(entry != null) {
current.add(entry.getKey());
}
}
return current;
}
public Set keysAsSet(){
HashSet current=新HashSet();
对于(条目:条目){
if(条目!=null){
current.add(entry.getKey());
}
}
回流;
}
代码与描述不匹配。也就是说,您正在调整循环内数组的大小,除非entries
中的第一个元素命中(即null
或它等于键)
您需要将数组大小调整放在循环之后(再加上修复循环条件检查):
@覆盖
公开作废认沽权(K键,V值){
int oldLength=this.entries.length;
for(int i=0;i
…我假设您知道这是一个非常低效的映射实现:每次搜索和插入都需要O(n)次尝试。实际上,您可以使用哈希表或某种搜索树来加快插入和查找速度。GenericarArrayHelper.CopyArrayWithiIncreasedSize是如何实现的?它只返回对Arrays.copyOf()的调用,因为调整大小发生在循环内部,然后尝试
this.entries[this.entries.length/2]=新条目(键,值)
然后直接返回代码>非常感谢。我知道这不是有效的,这只是任务告诉我要做的。然而,同样在您的实现中,调试器显示只有三个条目(直觉上,我认为这是正确的,因为这是我们输入的唯一条目),但在这种情况下,我不明白如何获得他们要求我的输出,每个条目列出两次。@DavidMoses根据描述判断,加倍的输出看起来像是问题中的错误,而不是故意的。如果是有意的,最简单的方法就是调用toString()
两次,当然了。我刚和我的导师联系过。这实际上是任务表本身的一个错误!这也是为什么我一开始就很困惑的原因。我原以为首先需要使用put()-方法将每个条目插入映射中两次,因此尝试相应地修改它。。。感谢大家指出了问题!
public Set<K> keysAsSet() {
HashSet<K> current = new HashSet<>();
for(Entry<K,V> entry : entries){
if(entry != null) {
current.add(entry.getKey());
}
}
return current;
}
@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);
}