通过引用操作对象
Manipulating an object through its reference
我正在编写 HashTable 的实现作为我课程中的练习,我正在使用一个 LinkedLists 数组,每个 LinkedLists 包含一个键值对(元素)来实现这一点。
我不想写 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]
时没有更新?
...my question is why isn't currentNode updated when list[key % size]
is updated?
因为 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 % size
替换为 index
。
也许这个架构会对你有所帮助:
Reference Heap Object
时刻 1:当前节点 -> 对象 1(空)
list[key % size] ->
时刻 2:当前节点 -> 对象 1(空)
list[key % size] -> object 2(new LinkedList<>();)
我正在编写 HashTable 的实现作为我课程中的练习,我正在使用一个 LinkedLists 数组,每个 LinkedLists 包含一个键值对(元素)来实现这一点。
我不想写 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]
时没有更新?
...my question is why isn't currentNode updated when list[key % size] is updated?
因为 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 % size
替换为 index
。
也许这个架构会对你有所帮助:
Reference Heap Object
时刻 1:当前节点 -> 对象 1(空)
list[key % size] ->
时刻 2:当前节点 -> 对象 1(空)
list[key % size] -> object 2(new LinkedList<>();)