从多个位置删除Java中的对象引用

时间:2018-05-20 03:16:38

标签: java

我有一个这样的课程:

Class Node {
   private String name;
   private Node next;

   public Node(String name) {
      this.name = name;
   }

   public void setNext(Node node) {
      this.next = node;
   }

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

我有一个示例节点:

Node node = new Node("abc");
Node n1 = new Node("def");

node.setNext(n1);

现在,如果我这样做:

n1 = null;
node.getNext()  <--  This returns new Node("def");

如何在不使用null方法的情况下返回setNext()。我有一个Node对象列表,如果从列表中删除任何Node对象,我想将所有next指针设置为null,指向已删除的节点。

有谁知道如何实现这一目标?

3 个答案:

答案 0 :(得分:0)

如果不使用setNext设置它,为什么不能这样做? 因为节点仍然具有n1的值,所以你必须将node.setNext也设置为null ....如果你希望从删除的节点中将所有下一个指针设置为null,那么你必须将整个事件循环到结束并且将它们中的每一个设置为null。

如果需要,可以在模型类中进行设置,但仍必须使用setNode

答案 1 :(得分:0)

如果不通过调用setNext设置null,则无法执行此操作,因为

节点node = new Node(“abc”); 节点n1 =新节点(“def”);

node.setNext(N1); - &GT;现在n1和next都指向堆中的同一个对象。

n1 = null; - &GT;这将使n1指向null但是next仍将指向堆中的Node对象。

答案 2 :(得分:0)

如果getNext()的调用频率高于setNext(...)(通常情况下),则可以执行以下操作:

import java.util.*;

public class Node {
    private String name;
    private Node next;
    private static final Map<Node, Set<Node>> backLinks = new HashMap<>();

    public Node(String name) {
        this.name = name;
    }

    public void setNext(Node node) {
        if (node == next)
            return;
        Set<Node> usedIn;
        if (next != null) {
            usedIn = backLinks.get(next);
            usedIn.remove(this);
        }
        if (node != null) {
            usedIn = backLinks.get(node);
            if (usedIn == null) {
                usedIn = new HashSet<>();
                backLinks.put(node, usedIn);
            }
            usedIn.add(this);
        }
        next = node;
    }

    public Node getNext() {
        return next;
    }

    // call this whenever you need to invalidate (exclude) a node
    public static void invalidate(Node node) {
        Set<Node> usedIn = backLinks.get(node);
        if (usedIn == null)
            return;
        for (Node n : usedIn)
            n.next = null;
        backLinks.remove(node);
    }

    public String toString() {
        return name;
    }

    public static void main(String[] args) {
        Node node = new Node("abc");
        Node n1 = new Node("def");
        node.setNext(n1);
        System.out.println(node.getNext());
        invalidate(n1);
        n1 = null; // optional
        System.out.println(node.getNext());
    }
}

否则,保留所有有效节点的集合,并在每次调用getNext()时查询它。改变行

private static final Map<Node, Set<Node>> backLinks = new HashMap<>();

private static final Set<Node> validNodes = new HashSet<>();

还要更改构造函数和接下来的三个方法:

    public Node(String name) {
        this.name = name;
        validNodes.add(this);
    }

    public void setNext(Node node) {
        next = node;
    }

    public Node getNext() {
        return validNodes.contains(next) ? next : null;
    }

    // call this whenever you need to invalidate (exclude) a node
    public static void invalidate(Node node) {
        validNodes.remove(node);
    }

此外,您可能希望在以下两种情况下将以下行添加到invalidate方法的末尾:

if (node.next != null)
    invalidate(node.next);

这将有效地删除链接到通过递归调用无效的节点的整个链。