我正在编写TreeMap的实现,并且遇到了get和put方法的问题。这是代码:
public class MyTreeMap<K extends Comparable<? super K>,V> extends AbstractMap<K,V> {
K key;
V value;
int height;
MyTreeMap<K,V> left,right;
int size;
private V get(K searchKey) {
if(this.isEmpty())
return null;//it needs an exception
if(this.key.compareTo(searchKey) == 0)
return this.value;
else if(this.key.compareTo(searchKey) > 0)
return this.left.get(searchKey);
else
return this.right.get(searchKey);
}
public V put(K key, V value) {
if(this.containsKey(key)) {
if(this.key.compareTo(key) == 0) {
V temp = this.value;
this.value = value;
return temp;
}
else if(this.key.compareTo(key) < 0)
return this.right.put(key, value);
else if(this.key.compareTo(key) > 0)
return this.left.put(key, value);
}
else {
if(this.isLeaf() || this.isEmpty()) {
if(this.key.compareTo(key) > 0) //this line gives NPE during tests
this.left = new MyTreeMap(key,value,null,null);
else
this.right = new MyTreeMap(key,value,null,null);
//check for balance and rebalance if needed
this.size++;
this.setHeight();
return null;
}
else {
if(this.key.compareTo(key) > 0)
return this.left.put(key, value);
else
return this.right.put(key, value);
}
}
}
最疯狂的错误是put方法需要另一个return语句。通过代码检查很多次,在我看来,情况应该不是这样,因为有一个return语句不需要任何布尔语句为真。
在测试put方法时,我得到了一个NPE。我认为我的代码存在一些非常重要的逻辑错误,因为我似乎无法弄清楚出了什么问题。如果你能指出我正确的方向来解决这些各种错误,那将是有帮助的。谢谢。
答案 0 :(得分:0)
关于“额外”return
声明:
if(this.containsKey(key)) {
if(this.key.compareTo(key) == 0) {
V temp = this.value;
this.value = value;
return temp;
}
else if(this.key.compareTo(key) < 0)
return this.right.put(key, value);
else if(this.key.compareTo(key) > 0)
return this.left.put(key, value);
}
您的逻辑是,您正在this.key.compareTo(key)
对<0
,>0
和==0
进行检查,以便涵盖所有案例。但是编译器的情况并非如此:
编译器不知道所有三次执行中this.key.compareTo(key)
的值是否相同。即使它具有检查方法的智能并且看到它不使用任何其他输入来获得结果(它没有),编译器也无法知道另一个线程是否同时更改了键的值。 / p>
即使您执行int value=this.key.compareTo(key)
并稍后对value
执行检查,编译器也不会检查连续的if-elsif是否涵盖了所有值范围。无论如何,出于性能/并发原因,我建议你使用这种方法只调用compareTo
一次。
最简单的解决方法是仅更改else if (this.key.compareTo(key) > 0)
的最后else
(因为您应该知道,如果执行该块是因为if必须为true。