gpt4 book ai didi

java - 对 Java 的垃圾收集器如何工作的困惑(节点 + 队列)

转载 作者:搜寻专家 更新时间:2023-11-01 02:23:55 25 4
gpt4 key购买 nike

<分区>

所以我一直在尝试用 Java 实现 LinkedList、Stack、Queue。

对于我使用的每个节点类,现在我真的不想讨论我的实现方式,因为我知道有更好的方法可以做到这一点,我只想专注于我的问题。

public class Node<E> {
private E data;
private Node<E> next;
private Node<E> prev;

public Node(E data) {
this.data = data;
this.next = null;
this.prev = null;
}

public E getData() {
return this.data;
}

public Node<E> getNext() {
return this.next;
}

public Node<E> getPrev() {
return this.prev;
}

public void setPrev(Node<E> prev) {
this.prev = prev;
}

public void setData(E data) {
this.data = data;
}

public void setNext(Node<E> next) {
this.next = next;
}
}

现在有了节点类,我一直对垃圾收集器的工作方式感到困惑,所以假设这是我的队列类

public class Queue<E> {
private int size;
private Node<E> head, tail;

public Queue() {
this.size = 0;
this.head = this.tail = null;
}

public Queue(E data) {
Node<E> temp = new Node<E>(data);
this.tail = this.head = temp;
this.size = 0;
}

public boolean enqueue(E data) {
Node<E> temp = new Node<E>(data);

if (this.head == null) {
this.tail = temp;
this.head = temp;
} else {
temp.setNext(this.head);
this.head.setPrev(temp);
this.head = temp;
}
this.size++;
return true;
}

public E dequeue() {
if (this.tail == null)
throw new IndexOutOfBoundsException();
else {
E data = this.tail.getData();
this.tail.setPrev(null);
this.tail = temp;
this.tail.setNext(null);
this.size--;
return data;
}
}

public int getSize() {
return this.size;
}

public E peak() {
if (this.tail == null)
throw new IndexOutOfBoundsException();
else
return this.tail.getData();
}

public boolean contains(E data) {
if (this.head == null)
return false;
else {
for (Node<E> cursor = this.head; cursor != null; cursor = cursor
.getNext()) {
if (cursor.getData().equals(data))
return true;
}
}
return false;
}
}

现在我对垃圾收集器的工作方式感到困惑。我听说,它会清除所有未指出的引用。因此,在执行

的部分,我的出队类中不断出现 nullpointerexception
 this.tail.setNext(null);

现在,听说垃圾收集器工作,没有什么可以引用它,所以我想我的节点是这样设置的

       head          tail
null<-[1]-><-[2]-><-[3]->null

每个节点都可以指向下一个和上一个,所以对于我的出列,我认为我必须做一些事情

1) 获取数据(很简单)

2) 得到一个指向前一个的临时节点

 Node<E> temp = this.tail.getPrev()

3) 现在这里是我开始迷路的地方,为了不再引用每个节点,我必须摆脱所有指向它的指针,所以这意味着我必须将

this.tail.setPrev(null);

因为当我在那之后删除节点时,我不能倒退去删除那个引用

       head               tail
null<-[1]-><-[2]-> null<-[3]->null
<-[temp]-> ( equals node [2])

4) 将尾部设置为指向临时节点,也就是上一个节点

this.tail = temp;

不应该是这样

       head   tail    
null<-[1]-><-[2]->(this still points to [3]) null<-[3]->null

5) 但是第二个节点还是指向了[3]的内存地址,所以我继续

this.tail.setNext(null); 

为了让它完全不引用我们不再存在的任何内存点,

       head   tail         will be deleted by GC
null<-[1]-><-[2]->null null<-[3]->null

但是,当队列中只剩下一个节点时,这部分会给我 NullPointerException

现在,我知道我在很多事情上可能是错的,我还在学习,但我只是不确定我必须对每个节点做多少事情才能确保垃圾收集器得到它,所以任何帮助都可以, 我需要将 prev 和 next 都设置为 null 吗?还是只有一个?等,所以任何帮助将不胜感激,谢谢 ;)

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com