首页 > 解决方案 > 通过引用操作对象

问题描述

我正在编写 HashTable 的实现作为我课程中的练习,我正在使用一个 LinkedList 数组,每个都包含一个键值对(元素)来实现这一点。我不想写list[key % size]来引用我正在操作的元素,而是写currentNode.

此代码抛出一个NullPointerException

public void put(int key, T value) {
        var currentNode = list[key % size];

        if(currentNode == null)
            list[key % size] = new LinkedList<>();
        else
            for(var item : currentNode)
                if (item.value == value)
                    return;
        currentNode.add(new Element<>(key, value));
    }

我知道发生错误是因为currentNode持有对空对象的引用,我的问题是为什么currentNode更新时list[key % size]不更新?

标签: javareference

解决方案


...我的问题是,当 list[key % size] 更新时,为什么 currentNode 没有更新?

因为currentNode不是list[key % size]. list数组中的元素和currentNode每个单独的变量在执行此语句后都包含相同的引用:

var currentNode = list[key % size];

当这些语句执行并且谓词计算为true

if(currentNode == null)
            list[key % size] = new LinkedList<>();

数组位置的变量[key % size]将包含对新创建的链表实例的引用。但是currentNode仍将包含null,因为分配未更新其引用。

要强制这两个变量对同一个实例具有相同的引用,您需要执行以下操作:

if(currentNode == null)
            currentNode = new LinkedList<>();
            list[key % size] = currentNode;
:
:

撇开性能不谈,%操作员是一项有点昂贵的操作。如果您希望put()表上的操作经常导致新的列表条目,那么在方法开始时将操作提升到赋值可能会更高效(并且肯定更具可读性):

public void put(int key, T value) {
        int index = key % size;
        var currentNode = list[index];

然后用 替换所有出现key % sizeindex


推荐阅读