【问题标题】:How to produce a functional LinkedList Class?如何生成功能性 LinkedList 类?
【发布时间】:2015-05-29 06:34:54
【问题描述】:

作为作业的一部分,我必须生成一个名为 Registry 的 LinkedList 类。它旨在成为具有界面的简单学生注册系统的一部分。

不幸的是,我真的碰壁了,不知道接下来要做什么。 Registry 类仅用于管理名为 studentList 的学生链接列表。

以下是我目前制作的目前相当不完整的课程。

import java.util.*;

public class Registry 
{
   LinkedList<Student> studentList;

   public Registry()
   {

   }

   public void addStudent(Student aStudent)
   {
      studentList.add(aStudent);
   }

   public void deleteStudent(int studentID)
   {
      studentList.remove(studentID);
   }

   @Override
   public String toString()
   {
      return getClass().getName() + 
   }

   public String format()
   {
      System.out.format(studentList);
   }
}

现在,我主要担心的是使用 Student。作为作业的一部分,我不得不创建另一个名为 Student 的类,它创建学生实例,其中包含姓名、姓氏、学生 ID 和学位课程作为字符串。

我将如何使用该单独的类来添加到注册表中即时的 LinkedList?我怎样才能让 Registry 类充分发挥作用?

我会尽力应要求提供任何其他详细信息。我可能不清楚,所以如果我不清楚,请告诉我,我会尽力解释。

编辑:这是所要求的学生班级:

public class Student 
{
   private String foreName;
   private String surName;
   private String studentID;
   private String degreeScheme;

   public Student()
   {

   }

   public void setForeName(String foreName)
   {
       this.foreName = foreName;
   }

   public String getForeName()
   {
       return foreName;
   }

   public void setSurName(String surName)
   {
       this.surName = surName;
   }

   public String getSurName()
   {
       return surName;
   }

   public void setStudentID(String studentID)
   {
       this.studentID = studentID;
   }

   public String getStudentID()
   {
       return studentID;
   }

   public void setDegreeScheme(String degreeScheme)
   {
       this.degreeScheme = degreeScheme;
   }

   public String getDegreeScheme()
   {
       return degreeScheme;
   }

   @Override
   public String toString()
   {
       return getClass().getName() + "[foreName = " + foreName + " surName "
               + surName + " studentID " + studentID + " degreeScheme " 
               + degreeScheme + "]";
   }

   public void format()
   {
       System.out.format("%5s%20s%11s%20s", foreName, surName, studentID, degreeScheme);
   }
}

【问题讨论】:

  • 使用必填字段创建您的学生班级。使用参数化构造函数为 Student 类创建一堆对象,然后使用您定义的方法将它们添加到 Registry 类?
  • 您的注册表类包含一个链表。它本身不是一个链表。不清楚您所说的“我怎样才能让 Registry 类充分发挥作用”是什么意思 - 它现在 做什么?
  • 任务不是自己做链表实现,而不是使用Java内置的LinkedList类吗?
  • @AkashPradhan,我已经创建了一个学生类,你是建议我应该在注册表构造函数中添加类似的变量,还是我完全走错了路线?
  • 这个问题太模糊,无法回答。 “可运行”是什么意思?可编译?你不会“运行”一个类,除非它有一个 main 方法入口点,这在这种情况下会很奇怪。现在我可以看到您的 remove 方法看起来不对,但您确实需要更具体地提出问题。目前究竟出了什么问题?

标签: java oop linked-list


【解决方案1】:
import java.util.Iterator;
import java.util.LinkedList;

public class Tester {
  public static void main(String[] args) {
    Registry r = new Registry();
    r.addStudent(new Student("13", "John", "Doe", "Physics")); // Add a student to the Registry
    r.addStudent(new Student("212", "Jane", "Bow", "Chem")); // Add another Student
    System.out.println(r); // Print the Student List

    r.deleteStudent(212); // Deletes student with ID 212
    System.out.println(r);
  }
}


class Student {
  private String studentID;
  private String foreName;
  private String surName;
  private String degreeScheme;

  public Student(String studentId, String foreName, String surName, String degreeScheme) {
    this.studentID = studentId;
    this.foreName = foreName;
    this.surName = surName;
    this.degreeScheme = degreeScheme;
  }

  public void setForeName(String foreName) {
    this.foreName = foreName;
  }

  public String getForeName() {
    return foreName;
  }

  public void setSurName(String surName) {
    this.surName = surName;
  }

  public String getSurName() {
    return surName;
  }

  public void setStudentID(String studentID) {
    this.studentID = studentID;
  }

  public String getStudentID() {
    return studentID;
  }

  public void setDegreeScheme(String degreeScheme) {
    this.degreeScheme = degreeScheme;
  }

  public String getDegreeScheme() {
    return degreeScheme;
  }

  @Override
  public String toString() {
    return getClass().getName() + "[foreName = " + foreName + " surName " + surName + " studentID "
        + studentID + " degreeScheme " + degreeScheme + "]";
  }

  public void format() {
    System.out.format("%5s%20s%11s%20s", foreName, surName, studentID, degreeScheme);
  }
}


class Registry {
  LinkedList<Student> studentList;

  public Registry() { // Creates studentList
    studentList = new LinkedList<>();
  }

  public void addStudent(Student aStudent) {
    studentList.add(aStudent);
  }

  public void deleteStudent(int studentID) {
    int index = searchList(studentID); // Gets index of the student in the Registry
    if (index == -1)
      throw new IllegalArgumentException("Student not found");
    // Since studentList is implemented as LinkedList, .remove removes element at specified position
    studentList.remove(index);
  }

  // Search by studentID , if found, return position in the list
  private int searchList(int studentID) {
    Iterator<Student> it = studentList.iterator();
    int count = -1;
    while (it.hasNext()) {
      count++;
      Student temp;
      temp = it.next();
      if (Integer.parseInt(temp.getStudentID()) == studentID) {
        return count;
      }
    }
    return -1;
  }

  @Override
  //Suggestions to improve the toString are welcome
  public String toString() {
    for (Student student : studentList) {
      student.format();
      System.out.println();

    }

    return "";
  }
}

【讨论】:

  • 我唯一的挑剔是我遵循一个特定的模板,我必须在 Registry 类中将 studentID 保留为 int。有没有其他方法可以移除学生?
  • 但是你的 Student class 说 studentID 是字符串(更新了答案)
  • 是的,但我必须使用导师提供的模板。专门使用了 String 和 int 学生 ID。
【解决方案2】:

在任何数据结构中,几乎总是需要实现三个函数:

  1. 插入
  2. 正在搜索
  3. 删除

让我首先阐明一般的链表结构由什么组成。 链表通过对节点进行操作来工作。每个节点都包含您要存储/修改/访问的实际数据。

  • Registry:这应该负责维护结构并提供一种在列表中插入/搜索/删除特定节点的方法。
  • 学生:存储数据并控制如何访问和修改数据

到目前为止,您已经正确创建了 Registry 框架。 (虽然你会想要实现一个搜索方法。)

对于您的学生班级,您只需创建所需班级的成员变量,以及适合他们的 getter/setter。

public class Student {
   private String id;
   private String forename;
   private String surname;
   private String degreeScheme;
   private Student next;  // Maintains a reference to the next node in the list

   Student () {
    //Default constructor values
   }

   Student (String id, String forename, String surname, String degreeScheme, Student next) {
      this.id = id;
      this.forename = forename;
      this.surname  = surname;
      this.degreeScheme = degreeScheme; 
      this.next = next;
   }

   public void setID (String id) {
      this.id = id;
   }

   public String getID () {
      return id;
   }

   public void setforename (String forename) {
      this.forename = forename;
   }

   public String getforename () {
      return forename;
   }

   public void setSurname(String surname) {
      this.surname = surname;
   }

   public String getSurname () {
      return surname;
   }

   public void setDegreeScheme(String degreeScheme) {
      this.degreeScheme = degreeScheme;
   }

   public String getDegreeScheme () {
      return degreeScheme;
   }

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

   public Student getNext () {
      return next;
   }
} //End Student Class

这应该是您入门的良好基础。请记住,在创建数据结构时,您可以通过确保明确关注点分离来避免很多麻烦。让学生类完全负责存储和维护数据,并让 Registry类负责维护结构本身!

此时,您可以在 Registry 类中使​​用 Student 类,只需根据需要插入节点,搜索它们,根据需要删除它们。

【讨论】:

  • "这应该是您入门的良好基础。"我不同意。一方面,它对我大喊“关注点分离”——为什么要把“链表”和“学生信息”的概念混为一谈呢?根据 OP 的 Registry 类,LinkedList&lt;Student&gt; 是一个非常 更好的主意。此外,我鼓励 OP 考虑使 Student 不可变(出于正常原因),并遵循正常的 Java 命名约定。我看不出这段代码回答了这个问题(目前 IMO 太模糊,无法回答)——它只是给 Student 类提供了一个不好的建议。
  • 好吧,您可以将学生类实现为注册表类中的链表。 @JonSkeet 这是创建列表的节点,在注册表类中使用。 IMO,这段代码显示了他的列表“节点”的结构是如何布置的。这很容易实现。
  • 但它混合了“我想要一个链表”和“我想要一个学生”的担忧。如果在某个时候应该将学生存储在一个集合中怎么办?此时,“下一个”字段无关紧要。它基本上不是学生状态的一部分——它是链表中节点状态的一部分,所以应该保留在那里。
  • @JonSkeet 如果您问我,这很简单,那时您可以直接删除该字段。此外,OP 从未提及可能需要转换结构。
  • 您的Student 类是“关于学生的数据”和“链表节点”的混合体。 Student 类中没有任何固有 链接列表相关的内容。这里不需要有一个“自定义”链表。只需在注册表中维护LinkedList&lt;Student&gt; 即可。我敢说你确实不同意反对票——如果你不反对的话会有点奇怪——但我肯定会留下来,因为你在支持它的答案中违反了 SoC。
猜你喜欢
  • 2015-10-30
  • 2021-05-25
  • 1970-01-01
  • 1970-01-01
  • 2016-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多