简体   繁体   中英

Java TreeMap implementation get and put methods

I'm writing an implementation of TreeMap, and am having trouble with the get and put methods. Here is the code:

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

The craziest error is that the put method requires another return statement. Checking through the code a bunch of times, it seems to me that this should not be the case, as there is a return statement that does not require any boolean statement to be true.

While testing the put method, I get an NPE. I think there are some pretty significant logic errors with my code, because I cannot seem to figure out what is wrong. If you could please point me in the right direction to fix these various errors, that would be helpful. Thank you.

About the "extra" return statement:

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

Your logic is that you are checking this.key.compareTo(key) against <0 , >0 and ==0 so you have all your cases covered. But this is not the case for the compiler since:

  1. The compiler does not know if the value of this.key.compareTo(key) is the same in all three executions. Even if it had the intelligence of checking the method and seeing that it does not use any other input to get the result (it does not), the compiler has no way of knowing if another thread is concurrently changing the values of the keys.

  2. Even if you do int value=this.key.compareTo(key) and later perform the checks against value , the compiler does not check that the successive if-elsif cover all the ranges of values. Anyway, for performance / concurrency reasons, I suggest you use this approach to only call compareTo once.

The easiest fix would be just changing the last else if (this.key.compareTo(key) > 0) for just else (as you should know that if that block is executed is because the if must be true.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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