2016-09-18 141 views
0

你好,我有這個程序的問題,它應該將學生信息存儲到Student類型的對象中。存儲信息:姓氏,年級和選票。投票存儲在IntegerArrayList中。每當我創建一個Student類型的新對象,並將其添加到類型爲Student(它存儲學校的所有學生)的ArrayList時,它會不斷添加我輸入的前一個Student對象創建的新投票,存儲在ArrayList在對象中傳遞ArrayList

例子:我添加Student給學生ArrayList,我給在輸入弗雷迪,5b和123,然後我檢查學生ArrayList,它包含了我已經加入學生:我再添弗雷迪,5b和123。我給學生輸入josh,4t和1234我檢查

爲什麼它會修改已經創建並存儲在ArrayList中的對象?我該如何解決它?

下面的代碼:

public class Student { 
    private String lastname; 
    private String grade; // example "4b" 
    private ArrayList<Integer> student_votes; 


    public Student(String lastname, String grade, ArrayList<Integer> student_votes) { 
     this.lastname=lastname; 
     this.grade=grade; 
     this.student_votes=student_votes; 
    } 

    public ArrayList getVotes() { 
     return student_votes; 
    } 

    public String getLastname() { 
     return lastname; 
    } 

    public String getGrade() { 
     return grade; 
    } 

    public String toString() { 
     return lastname+" "+grade+" "+getVotes(); 
    } 

    public void print_student (Student student) { 
     System.out.println(student); 
    } 

    public static void print_students(ArrayList<Student> students) { 
     for(Student s : students) { 
      System.out.print(s); 
     } 
     System.out.println(""); 
    } 

    public static void menu() { 
     System.out.println("\nPress 1 to add a student\nPress 2 to remove a student\nPress 3 to print the classroom\nPress 4 to exit"); 
    } 

    public static void main(String[] args) { 
     int choice, nv=0, i=0,average=0; 
     Boolean exit=false; 
     ArrayList<Student> students = new ArrayList<Student>(); 
     ArrayList<Integer> votes = new ArrayList<Integer>(); 
     String lastname = new String(); 
     String grade = new String(); 

     Scanner sc = new Scanner(System.in); 
     Scanner st = new Scanner(System.in); 
     do { 
      menu(); 
      choice=sc.nextInt(); 

      switch (choice) { 
       case 1: System.out.println("Enter your lastname:"); 
         lastname=st.nextLine(); 
         System.out.println("Enter your grade:"); 
         grade=st.nextLine(); 

         System.out.println("Enter the amount of votes"); 
         nv=sc.nextInt(); 



         for(i=0;i<nv;i++) { 
          System.out.println("Enter vote n:"+(i+1));     
          votes.add(sc.nextInt()); 
         } 

         students.add(new Student(lastname,grade,votes)); 
         System.out.println("student added!"); 

         break; 

       case 2: System.out.println("Enter student position: "); 
         nv = sc.nextInt(); 
         students.remove(nv-1); 
         break; 

       case 3: print_students(students); 
         break; 

       case 4: exit = true; 

      } 
     } while (exit==false); 
    } 
} 
+2

爲什麼有兩個掃描儀?您只能使用一個,但仍可實現相同的目標。 –

+1

您正在爲每個學生設置相同的列表對象。如果你想要不同的內容,你需要構建一個單獨的。 – shmosel

+0

@shmosel所以我需要爲每個學生創建一個數組列表?有沒有辦法避免這種情況? – BlueJay

回答

0

對於每個學生您都使用相同的ArrayList進行投票,每個學生都擁有相同投票的相同列表(當您將列表添加到student-1時,讓我們說2票,然後將列表添加到student-2 with 3 votes,then both students will have 5 votes now),change this like like:

votes = new ArrayList<Integer>(); 
for(i=0;i<nv;i++) 
{ 
    System.out.println("Enter vote n:"+(i+1)); 
    votes.add(sc.nextInt()); 
} 

現在應該沒問題。你也使用2個掃描儀,這是不必要的,1就足夠了。

1

您使用相同的ArrayList對象爲每個StudentStudent不包含列表的副本,而是指向同一列表的指針。如果通過任何一個指針不斷添加到列表中,所有這些指針都會受到影響。

您應該爲每個學生創建一個new ArrayList並將其傳遞給構造函數。

1

問題出在您輸入投票的邏輯上,您正在使用一個ArrayList來收集所有將投放給任何學生的選票。

當您傳遞一個對象時,您不會複製該對象,但是您將引用該對象,這意味着使用您的邏輯,所有學生將擁有與您的main中的投票ArrayList相同的引用。這可以通過對每個學生創建一個新的ArrayList迎刃而解:

System.out.println("Enter the amount of votes"); 
nv=sc.nextInt(); 
final ArrayList<Integer> votes = new ArrayList<>(); 
for(i=0;i<nv;i++) 
{ 
    System.out.println("Enter vote n:"+(i+1)); 
    votes.add(sc.nextInt()); 
} 

這會爲您解決問題,但確實是在我看來,使用一個ArrayList,你會知道的金額投票沒有意義的。 然後代碼將是這個,但是學生需要進行修改,以接受一個數組:

System.out.println("Enter the amount of votes"); 
nv=sc.nextInt(); 
final int[] votes = new int[nv]; 
for(i=0;i<nv;i++) 
{ 
    System.out.println("Enter vote n:"+(i+1)); 
    votes[i] = sc.nextInt(); 
}