简体   繁体   English

Arraylist的最后一个元素覆盖先前的元素

[英]Arraylist last element overwriting previous elements

I have a code that allows teacher to add students and view them, but everytime I add a student, the previous student would get overwritten as well. 我有一个允许老师添加学生并查看他们的代码,但是每次添加一个学生时,以前的学生也会被覆盖。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">

<h:body>
<h:form>
    <h1><label>Student Grades</label></h1>
    <hr />
    <h:dataTable value="#{course.studentList}" var="st" border="1" rendered="#{course.render}">
        <f:facet name="caption">#{course.courseCode} #{course.courseName}</f:facet>
        <h:column>
            <f:facet name="header">Student Name</f:facet>
            <h:outputText value="#{st.studentName}" />
        </h:column>
        <h:column>
            <f:facet name="header">Score</f:facet>
            <h:outputText value="#{st.studentScore}" />
        </h:column>
    </h:dataTable><br />
    <label>Student Name</label>
    <h:inputText id="studentName" label="Student Name" value="#{student.studentName}" required="true" requiredMessage="Please enter a student name">
    </h:inputText>
    <h:message for="studentName" /><br />
    <label>Student Score</label>
    <h:inputText id="studentScore" label="Student Score" value="#{student.studentScore}" required="true" converterMessage="You must enter a number">
    <f:validateDoubleRange minimum="0" maximum="100" />
    </h:inputText>
    <h:message for="studentScore" /><br />
    <h:commandButton value="Add Grade" action="#{course.add(student)}"/>
    <h:commandButton value="Submit" action="summary"/>
</h:form>
</h:body>
</html>

Below is the student.java 下面是student.java

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean(name = "student")
@SessionScoped
public class Student {
private String studentName;
private Double studentScore;

public String getStudentName() {
    return studentName;
}

public void setStudentName(String studentName) {
    this.studentName = studentName;
}

public Double getStudentScore() {
    return studentScore;
}

public void setStudentScore(Double studentScore) {
    this.studentScore = studentScore;
}
}

Below is the Course.java which has an arraylist of students. 以下是Course.java,其中包含学生的数组列表。

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import java.util.ArrayList;

@ManagedBean(name = "course")
@SessionScoped
public class Course {
private String courseName;
private String courseCode;
private ArrayList<Student> studentList = new ArrayList<Student>();
private double courseAverage;
private boolean render;

public String getCourseName() {
    return courseName;
}

public void setCourseName(String courseName) {
    this.courseName = courseName;
}

public String getCourseCode() {
    return courseCode;
}

public void setCourseCode(String courseCode) {
    this.courseCode = courseCode;
}

public ArrayList<Student> getStudentList() {
    return studentList;
}

public void setStudentList(ArrayList<Student> studentList) {
    this.studentList = studentList;
}

public double getCourseAverage() {
    int i = 0;
    for (Student st : studentList) {
        courseAverage += st.getStudentScore();
        i++;
    }
    return courseAverage/i;
}

public void setCourseAverage(double average) {
    this.courseAverage = average;
}

public boolean isRender() {
    return render;
}

public void setRender(boolean render) {
    this.render = render;
}

public String add(Student student) {
    studentList.add(student);
    render = true;
    return null;
}

public String reset() {
    studentList = new ArrayList<Student>();
    courseName = "";
    courseCode= "";
    courseAverage = 0.0;
    render = false;
    FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
    return "home";
}

public boolean renderable() {
    boolean render = false;
    for (Student st : studentList) {
        render = true;
    }
    return render;
}
}

As your Student class is annotated as a @SessionScoped @ManagedBean , it will be created and stored throughout the user's HTTP session, ie unless it is invalidated, or it expires. 当您的Student类被标注为@SessionScoped @ManagedBean ,它将在整个用户的HTTP会话中创建和存储,即除非该类无效或过期。 So, when you add a value to your list you basically add a very same reference everywhere and all you do is modify the fields of a Student object that was once created and later its fields were continuously replaced and, thus, every list element that contains a reference to the same Student object, was modified as well. 因此,当您向列表中添加一个值时,基本上到处都添加了一个完全相同的引用,而您所做的就是修改曾经创建的Student对象的字段,后来又连续替换了其对象,因此, 每个包含对同一 Student对象的引用也已修改。

What you need to do is to create a brand new Student object that is to be added to the list and for this essentially removing any bean annotations from it. 您需要做的是创建一个全新的Student对象,该对象将被添加到列表中,并为此从其中删除所有bean注释。

As a side note, be sure to understand the differencebetween and use cases of a managed bean and a model/placeholder before you proceed any further. 附带说明,在继续进行任何操作之前,请务必了解托管Bean和模型/占位符的用例之间的区别。

In the Course.add method add a copy of the parameter student . Course.add方法中,添加参数student的副本。

Reason: even a request-scoped bean could get repeated/reused by the container. 原因:即使请求范围的bean也会被容器重复/重用。 In every case it is a bit more defensive. 在每种情况下,它都更具防御性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM