1

私は現在、Java で Map クラスを作成する課題に取り組んでおり、'put' メソッドを使用しているときに修正できないエラーが発生しました。基本的に、テストを実行すると、マップ内に新しいノードが作成されず、その理由がわかりません。前もって感謝します!

クラス:

public class MyMap<K extends Comparable<K>, V> {
private class MapNode {
    private K key;
    private V value;
    private MapNode left;
    private MapNode right;

    public MapNode(K theKey, V theValue) {
        key = theKey;
        value = theValue;
        left = null;
        right = null;
    }
}

private MapNode root;

public MyMap() {
    root = null;
}

/**
 * Associates key to value and stores mapping If key exists, replaces value
 * with a new value
 * 
 * @param key
 * @param value
 * @return value replaced; null if no value
 */

public V put(K key, V value) {
    return put(key, value, root);
}

private V put(K key, V value, MapNode ref) {
    V temp;
    if (ref == null) {
        ref = new MapNode(key, value);
        return null;
    } else {
        if (ref.key.compareTo(key) == 0) {
            temp = ref.value;
            ref.value = value;
            return temp;
        } else if (key.compareTo(ref.key) < 0)
            return put(key, value, ref.left);
        else
            return put(key, value, ref.right);
    }
}

/**
 * Return value to which key is mapped
 * 
 * @param key
 * @return value of key; null
 */

public V get(K key) {
    return get(key, root);
}

private V get(K key, MapNode ref) {
    if (ref == null) {
        return null;
    } else {
        if (ref.key.compareTo(key) == 0)
            return ref.value;
        else if (key.compareTo(ref.key) < 0)
            return get(key, ref.left);
        else if (key.compareTo(ref.key) > 0)
            return get(key, ref.right);
        else
            return null;
    }
}

/**
 * Returns true if Map already uses the key
 * 
 * @param key
 * @return true; false
 */

public boolean containsKey(K key) {
    return containsKey(key, root);
}

private boolean containsKey(K key, MapNode ref) {
    if (ref == null) {
        return false;
    } else {
        if (ref.key.compareTo(key) == 0)
            return true;
        else if (key.compareTo(ref.key) < 0)
            return containsKey(key, ref.left);
        else if (key.compareTo(ref.key) > 0)
            return containsKey(key, ref.right);
        else
            return false;
    }
}
}

テスト:

import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class MyMapTest {
@Test
public void testMyMap(){
    MyMap<String, Integer> m = new MyMap<String, Integer>();

    assertFalse(m.containsKey("one"));
    assertEquals(null, m.get("one"));
    assertEquals(null, m.put("one", 1));
    assertTrue(m.containsKey("one"));
}
}
4

3 に答える 3

2

メソッド内で、追加するノードを含むput(K key, V value, MapNode ref)新しい MapNode を割り当てます。ref

を渡してそのメソッドを呼び出していることがわかりますroot。これは、 に保存されているのと同じ参照を保存しrootますrefrootこれが意味することは、 null でない場合、同じオブジェクトを指すということです。ただし、そのままrootではnull、どちらも を指していnullます。

を割り当てると、新しいノードをref = new MapNode(key, value);指しますが、それでも null を指します。refroot

root新しい MapNodeをポイントする必要があります。それをポイントしてrefも、それはできません。

于 2012-04-19T20:17:34.480 に答える
0

問題は、ルートをどこにも変更しないため、 Map に何も含まれないことです。参照ではなく値で渡しているため、これを行うとref = new MapNode()、呼び出し元の値ではなく、ローカル変数が変更されます。

于 2012-04-19T20:17:50.343 に答える
0

あなたの問題は、Java が参照渡しではないという事実を見失っていることです。値渡しで参照を渡します。あなたが言うときref = new MapNode(...)、あなたは実際には何も変えていません。親ノードが新しく作成されたノードを指すように明示的に設定する必要があります。

于 2012-04-19T20:18:04.463 に答える