Java:跟踪链接列表中的属性?

Java:跟踪链接列表中的属性?,java,performance,list,loops,nullpointerexception,Java,Performance,List,Loops,Nullpointerexception,这是我为之而写的一种方法。它基本上记录了一场刺客游戏 在刺客游戏中,每个人都有一个目标,但他们不知道自己是谁的目标。游戏的目标是在活着的时候“杀死”你的目标。我正在写一个类,它跟踪一个由谁和他们各自的目标所针对的人的列表,同时还处理在有人被杀时对列表的更改 这个名单被称为杀人环(暗杀目标的环形链)。例如,如果您有4名玩家,分别名为Sally、Matthew、Evan和Christina,一种可能的配置是: 莎莉-->马修-->埃文-->克里斯蒂娜-->回到莎莉身边 kill方法记录了对具有给定姓

这是我为之而写的一种方法。它基本上记录了一场刺客游戏

在刺客游戏中,每个人都有一个目标,但他们不知道自己是谁的目标。游戏的目标是在活着的时候“杀死”你的目标。我正在写一个类,它跟踪一个由谁和他们各自的目标所针对的人的列表,同时还处理在有人被杀时对列表的更改

这个名单被称为杀人环(暗杀目标的环形链)。例如,如果您有4名玩家,分别名为Sally、Matthew、Evan和Christina,一种可能的配置是:

莎莉-->马修-->埃文-->克里斯蒂娜-->回到莎莉身边

kill
方法记录了对具有给定姓名的人的杀害,将该人从杀人环转移到墓地(列出了所有被杀人员的姓名)

杀人环由
刺客节点
组成,与
链接列表
中的
链接节点
非常相似,不同之处在于
刺客节点
有三个字段:人名(
this.name
),刺客的姓名(
this.killer
)和引用其目标的指针(
this.next

如果您需要有关
节点
的更多详细信息,请参阅上面列出的分配规范

我很难跟踪凶手的名字,而不会出现
NullPointerException
或彻底的低效。我已经解决了中间的情况(链接列表的中间部分)(我想),但是我在前面和后面的情况下遇到了问题

如果你需要更多信息,请告诉我

public void kill(String name) {
    if (gameOver()) {
        throw new IllegalStateException("The game is now over.");
    } else if (!killRingContains(name)) {
        throw new IllegalArgumentException("This person is not listed in the kill ring."); 
    }
    AssassinNode previous = null;
    AssassinNode current = front;        
    while (current != null) {
        if (name.equalsIgnoreCase(current.name)) {
            if (current.equals(front)) {
                front = front.next;
            } else if (current.next == null) {
                previous.next = null;
            } else {
                previous.next = current.next;
                current.killer = previous.name;
            }

            if (graveyard == null) {
                graveyard = current;
                graveyard.next = null;
            } else {
                current.next = graveyard;
                graveyard = current;
            }
           return;
        } else {
            if (previous == null) {
                previous = front;
            } else {
                previous = previous.next;
            }
            current.killer = previous.name; //added
            current = current.next;
        }
    }
}

如果您只想知道谁还活着,而不必遍历列表,那么应该使用Map()()。映射允许您按名称(键)存储对象并快速检索它。存储的对象应该是您的AssasinNode,它依次保留对下一个(和上一个)节点的引用


调用“kill”方法时,在映射中查找节点,将其删除,如果它有“previous”和“next”节点,则使它们相互指向。边缘情况是指只有一个节点,即它自己的网络和前一个节点。然后,只需将其从映射中删除,什么也不做。

在这种情况下,我发现绘制数据结构的图表并在这些图表上一步一步地重放代码很有用

在您的情况下,当您尝试删除第一个节点时,您正确地调整了前指针,但实际上从未取消节点与环的链接:您只是将其发送到墓地,而环中的前一个节点仍指向它

请记住,您的数据结构是一个环:它没有正面或背面(这也意味着.next永远不会为null),因此在节点移除期间的“正面”点是不相关的-您只需要在之后将其调整到一个幸存的节点。提示:

AssassinNode previous = front;
从风格上讲,我更喜欢将前面/当前的步骤写成

previous = current;
current = current.next;

前进时通常不需要检查'previous==null'。

我会递归地这样做。找到要杀死的一个,把它送到墓地,然后在堆栈展开时重建列表。