2016-09-18 196 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(); 
}