让一个对象记住下一个同类对象



好吧,尽管这个话题可能很模糊,但让我首先承认这是一个与家庭作业有关的问题。所以,如果你对这些问题有一些有趣的报复,请注意。

不过,我已经和它坐了好几个小时了,我很不好意思还没有"得到它"。

所以我希望你们中的一些人能告诉我我错过了什么。

我要创建一个类,它存储一个变量,并记住该类的下一个对象。

以下是我的主要课程:

public class SticksAndStones {
public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    String response = "n";
    Stick currentStick = null;
    int numberOfSticks = 0;
    while (response.equals("n")) {
        System.out.println("What diameter should the stick have?");
        response = Integer.toString(scan.nextInt());
        currentStick = new Stick(Integer.parseInt(response), currentStick);
        numberOfSticks++;
        System.out.println("Are you done adding sticks? ('n' or 'y')");
        response = scan.next();
        while (!response.equals("y") && !response.equals("n")) {
            System.out.println("Please type 'y' for yes, or 'n' for no.");
            response = scan.next();
        }
    }
    for (int i = 0; i < numberOfSticks; i++) {
        System.out.println(currentStick.getDiameter());
        currentStick = currentStick.getNext();
    }
}
}

我的Stick类看起来像:

public class Stick {
int diameter;
Stick stick;
public Stick(int diameter, Stick stick) {
    this.diameter = diameter;
    this.stick = stick;
}
public int getDiameter() {
    return diameter;
}
public Stick getNextStick() {
    return stick;
}

现在,正如你所看到的,我的班级似乎能够记住上一棒,但无论如何都记不住下一棒。

这是一个问题,因为在我的SticksAndStones课程的底部,我试图打印出每个棍子的直径,但它们没有按正确的顺序打印出来。换句话说,第一根棍子是最后一根出来的,最后一根棍子是第一根出来的。

我不需要。我需要他们从另一个方向出来。第一次坚持,就像第一次坚持。

我们在这项任务中唯一的限制是,我们不能使用任何形式的数组、列表、表或数据库

我是不是错过了一些非常简单的东西?

PS:会使用"作业"标签,但不允许。

更新

新贴纸和石头类:

import java.util.Scanner;
public class SticksAndStones {
public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    String response = "n";
    int numberOfSticks = 0;
    Stick firstStick = null;
    Stick currentStick = null;
    ;
    Stick prevStick = null;
    while (response.equals("n")) {
        System.out.println("What diameter should the stick have?");
        response = Integer.toString(scan.nextInt());
        if (firstStick == null) {
            firstStick = new Stick(Integer.parseInt(response));
            prevStick = firstStick;
        } else {
            currentStick = new Stick(Integer.parseInt(response));
            prevStick.setNextStick(currentStick);
            prevStick = currentStick;
        }
        numberOfSticks++;
        System.out.println("Are you done adding sticks? ('n' or 'y')");
        response = scan.next();
        while (!response.equals("y") && !response.equals("n")) {
            System.out.println("Please type 'y' for yes, or 'n' for no.");
            response = scan.next();
        }
    }
    currentStick = firstStick;
    for (int i = 0; i < numberOfSticks; i++) {
        System.out.println(currentStick.getDiameter());
        currentStick = currentStick.getNextStick();
    }
}
}

我的贴纸类:

public class Stick {
int diameter;
Stick stick;
Stick nextStick;
public Stick(int diameter, Stick stick) {
    this.diameter = diameter;
    this.stick = stick;
}
public Stick(int diameter) {
    this.diameter = diameter;
}
public int getDiameter() {
    return diameter;
}
public Stick getNextStick() {
    return stick;
}
public void setNextStick(Stick nextStick) {
    this.nextStick = nextStick;
}
}

一个微笑和一个拥抱,谁能告诉我为什么我打了一个NullPointerException。

一点点重构会有很大帮助:

由于不可能知道构造时间next Stick是什么,构造函数不应将其作为参数,或者至少可以选择创建没有nextStick 的对象

public Stick(int diameter) {
    this.diameter = diameter;
}

在你开始循环添加贴纸之前,你保留了3个参考:

Stick firstStick = null;
Stick currentStick;
Stick prevStick = null;

在你的while loop中,在你询问直径后,你会检查初始棒是否已经定义,或者你是否在不断添加棒。。。

if (firstStick == null) {
    firstStick = new Stick(Integer.parseInt(response));
    prevStick = firstStick;                
} else {
    currentStick = new Stick(Integer.parseInt(response));
    prevStick.setNextStick(currentStick);
    prevStick = currentStick;
}

在循环外打印信息时,您将currentStick设置为指向firstStick,并始终循环

currentStick = firstStick;
for (int i = 0; i < numberOfSticks; i++) {
    System.out.println(currentStick.getDiameter());
    currentStick = currentStick.getNextStick();
}

更新

根据您对Stick级的更改

这应该是的样子

public class Stick {
    int diameter;
    Stick stick;
    public Stick(int diameter) {
        this.diameter = diameter;
    }
    public int getDiameter() {
        return diameter;
    }
    public Stick getNextStick() {
        return stick;
    }
    public void setNextStick(Stick stick) {
        this.stick = stick;
    }
}

很明显,当第一次创建下一个棒时,Stick无法"记住"它,因为还没有下一个。但是,如果唯一的Stick构造函数将前一个stick作为参数,那么——尽管它很难看——它可以修改前一个tick以引用新的stick:

public Stick(int diameter, Stick previousStick) {
    this.diameter = diameter;
    this.previous = previousStick;
    previousStick.next = this;
}

当然,假设Stick类中有一个新的和一个重命名的字段。

然而,最好在创建新的Stick之后添加前向引用,这样Stick构造函数就不会修改其参数:

public Stick(int diameter, Stick previousStick) {
    this.diameter = diameter;
    this.previous = previousStick;
}
// ... main() ...
    Stick newStick = new Stick(Integer.parseInt(response), currentStick);
    currentStick.setNext(newStick);

此外,如果您希望能够向前遍历链表(这就是您正在创建的),那么您需要在某个位置保留对第一个Stick的引用。如果不需要反向遍历列表,则可以省略对该引用的跟踪(在这种情况下,Stick构造函数不需要将Stick作为参数)。剩下的我交给你解决。

避免添加第二个引用以使每个Stick记住前一个引用的另一个选项是编写一个递归方法,对Stick链进行订单后遍历:

public static void printSticks(Stick s) {
  if (s != null) {
    printSticks(s.getNextStick());
    System.out.println(s.getDiameter());
  }
}

这种方法不适合很长的列表,因为它会出现堆栈溢出错误,但它是一个例子,说明了如何使用递归算法来绕过您一直在使用的数据结构的限制。

您可以让您的班级了解上一小节和下一小节。

public class Stick {
    private int diameter;
    private Stick previousStick;
    private Stick nextStick;
    public Stick(int diameter, Stick previousStick, Stick nextStick) {
        setDiameter(diameter);
        setPreviousStick(previousStick);
        setNextStick(nextStick);
    }
    //getters and setters
}

然后在您的主方法中,您需要适当地设置它们。这是你应该"做作业"的地方。以下是一些入门帮助。思考如何使用它。

Stick lastStick;
Stick currentStick;
lastStick = currentStick;
currentStick = new Stick(diameter, lastStick, null);
lastStick.setNextStick(currentStick);

最新更新