自定义化的链表在实际中的应用

问题遇到的现象和发生背景

题目是关于linkedlist, 每次测试运行显示 Payment是null

用代码块功能插入代码,请勿粘贴截图
public class Payment {

  public String fromPerson; // name of Person paying
  public String toPerson; // name of Person receiving payment
  public double amount; // amount payed
  public Timestamp timestamp; // unique time stamp (provided at the time of creation)
  public Payment next; // reference to next payment in appropriate Ledger Linked List

  /**
   * Basic empty constructor for a payment
   */

  public Payment() {
    // Provided - not to be changed
    this.fromPerson = null;
    this.toPerson = null;
    this.amount = 0;
    this.timestamp = null;
    this.next = null;
  }

  /**
   * Payment constructor with all necessary fields to be inserted in Ledger
   * 
   * @param fromPerson is the person paying
   * @param toPerson   is the person receiving the payment
   * @param amount     is the amount payed
   * @param timestamp  is time at creation of payment
   * @param next       is the next payment
   */

  public Payment(String fromPerson, String toPerson, double amount, Payment next) {
    // Provided - not to be changed
    this.fromPerson = fromPerson;
    this.toPerson = toPerson;
    this.amount = amount;
    this.timestamp = new Timestamp(); // time stamp is automatically set at creation
    this.next = next;
  }

  /**
   * A Payment is valid if it is done between registered persons provided in the
   * array persons
   * 
   * You may assume that the input array (String[] persons) will
   * not be null or empty.
   * 
   * @param persons - array of persons who can make and receive payment
   * 
   * @return true if the Payment is valid based on the criteria listed above,
   *         false otherwise
   */
  public boolean isValid(String[] persons) {
          boolean flag1=false;
          boolean flag2=false;
    for(int i=0;iif(this.fromPerson.toLowerCase().equals(persons[i].toLowerCase()))
          flag1=true;
       if(this.toPerson.toLowerCase().equals(persons[i].toLowerCase()))
          flag2=true;
      }
   return flag1&&flag2;
  }
}

public class Ledger {

  public Payment head;
  public int id;
  public Ledger next;

  // add attributes as needed
  // needed to implement efficient code
  // tested for `advanced' parts
  public Payment tail;

  /**
   * Default constructor
   * 
   * You may modify this constructor if you need to (e.g.
   * if you want to initialise extra attributes in the class)
   */
  public Ledger() {
    head = null;
    id = 0;
    next = null;
    //
    // add initialisation of added attributes, if needed
    
  }
  /**
   * Assign an id to the current Ledger
   * 
   * @param id
   */
  public void setId(int id) {
    //
    // Provided - not to be changed
    this.id = id;
  }
  /**
   * 
   * @return the number of payments in the Ledger
   */
  public int size() {

    Payment curr=head;
    int count=0;
    while(curr!=null) {
      count++;
      curr=curr.next;
    }
    return count;
  }

  /**
   * Add a payment at the end of the Ledger list
   * 
   * @param payment
   */
  public void addPayment(Payment payment) {

    // if Payment is null, do nothing
    Payment head=payment ;
    Payment temp=head;
    if(head!=null) {
    while(temp.next!=null) {  
      temp=temp.next;
    }
    temp.next= new Payment();
    }
  }

**TEST CASE :**

```java
 public void testLedgerSize() {

    assertTimeoutPreemptively(Duration.ofMillis(1000), () -> {

      String[] fromPerson = { "Eren", "Mikasa", "a", "c", "Armin", "Jean", "Levi", "Sakura", "Naruto", "Erwin",
          "Thomas",
          "Sasuke", "Ichigo", "Luffy", "Scarlet"
      };

      String[] toPerson = { "Levi", "a", "Mikasa", "c", "Jean", "Armin", "Sakura", "Levi", "Sasuke", "Erwin", "Scarlet",
          "Naruto", "Rukia", "Ichigo", "Thomas"
      };

      double[] payment = { 10.0, 100.1, 21.0, 55.5, 29.9, 99.9, 100.0, 29.99, 30.0, 24.95, 35.0, 34.49, 99.95, 50,
          400 };

      // String[] registeredPeople = {"Eren", "Levi", "Mikasa", "Armin", "Erwin",
      // "Jean", "Annie", "Reiner", "Hanji", "Sasha"};

      // Case 1: empty Ledger
      Ledger empty = new Ledger();
      assertEquals(0, empty.size());

      // Case 2: Non empty Ledger size computed accurately
      Ledger nonEmpty = new Ledger();
      for (int i = 0; i < fromPerson.length; i++) {
        nonEmpty.addPayment(new Payment(fromPerson[i], toPerson[i], payment[i], null));
      }

      assertEquals(toPerson.length, nonEmpty.size());

      // Case 3: Ledger with one Payment only
      Ledger singlePayment = new Ledger();
      singlePayment.addPayment(new Payment("Eren", "Levi", 100, null));

      assertEquals(1, singlePayment.size());

    });
    currentMethodName = new Throwable().getStackTrace()[0].getMethodName();
  }


我的解答思路和尝试过的方法

我有尝试加 constructor, initialize Payment 和 Ledger 让它不为null

我想要达到的结果

Ledger.size() and Ledger.addPayment()工作

怎么说呢,逻辑太混乱了,简单说几个错误的地方。

    public Ledger() {
        head = null; // head永远是null,下面也没有任何修改head的地方,当然你的size永远是0了。
        id = 0;
        next = null;
    }
    public void addPayment(Payment payment) {
        // 从你这个add方法实现来看,是把入参的payment当作了head,然后在其最后添加了一个new Payment();
        // 这样你必须要payment.size(),才会有结果啊,singlePayment.size()肯定还是0
        // 但是我想,或者说一个正常的add方法,目的肯定不是这样的,应该是直接把入参的payment添加到队尾。
        // 因此直接把下一行删掉即可。
        // Payment head=payment ;
        Payment temp=head;
        if(head!=null) {
            while(temp.next!=null) {
                temp=temp.next;
            }
            temp.next= new Payment();
        }
    }