使用一个Iterator Java迭代两个列表

时间:2012-03-01 16:18:06

标签: java arraylist iterator

我遇到了一些问题我有两个类,每个类都返回一个Iterator,有一个类返回名为Student的值。使用这段代码,我可以迭代一个类,我想知道是否有一种方法可以在我的Machine类中迭代另一个类而不添加第二个类。以下是我的代码的样子:

import java.util.*;
import java.lang.reflect.*;

class ClassRoom1{
    ArrayList<Student> al = new ArrayList<Student>();
    Student st; 
    public ClassRoom1(){
        st = new Student("Michael", "Smith", 12);
        al.add(st);
        st = new Student("Jennifer", "Lopez", 13);
        al.add(st);
    }

    public void addStudent(String name, String lastName, int age) {
        Student st = new Student(name, lastName, age);
        al.add(st);
    }

    public ArrayList getStudents(){
        return al;
    }

    public Iterator returnIter(){
        Iterator iter = getStudents().iterator();
        return iter;
    }
}

class ClassRoom2{
    ArrayList<Student> al = new ArrayList<Student>();
    Student st; 
    public ClassRoom2(){
        st = new Student("Brian", "Con", 15);
        al.add(st);
        st = new Student("Megan", "Bell", 15);
        al.add(st);
    }

    public void addStudent(String name, String lastName, int age) {
        Student st = new Student(name, lastName, age);
        al.add(st);
    }

    public ArrayList getStudents(){
        return al;
    }

    public Iterator returnIter(){
        Iterator iter = getStudents().iterator();
        return iter;
    }
}

public class Machine{
    Student st;
    ClassRoom1 clrm1 = new ClassRoom1();
    ClassRoom2 clrm2 = new ClassRoom2();    

    public static void main(String[] args){
        Machine mch = new Machine();
        ArrayList al = new ArrayList();
        Iterator iter = al.iterator();
        mch.printStudens(iter);
    }

    void printStudens(Iterator iter){
        iter = clrm1.returnIter();
        while(iter.hasNext()){
            st = (Student) iter.next();
            System.out.println("\nName: " + st.getName() + "\nLast name: " + st.getLastName() + "\nAge: " + st.getAge());
        }
    }
}

5 个答案:

答案 0 :(得分:4)

首先,使用OO:

代替代码重复
class ClassRoom{
    private List<Student> al;
    public ClassRoom1(List<Student> studentList){
        a1 = new ArrayList(studentList);
    }

    public void addStudent(String name, String lastName, int age) {
        al.add(new Student(name, lastName, age));
    }

    public List<Student> getStudents(){
        return al;
    }

    public Iterator<Student> returnIter(){
        return getStudents().iterator();
    }
}

然后clrm1clrm2是ClassRoom的对象。实际上,您可以在自己的列表中保存任意多个ClassRoom对象,并进行嵌套迭代,首先是所有ClassRooms,在其中迭代当前ClassRoom中的所有Student。


更新

如果你曾经需要组合迭代器(这里没有必要),我要么编写我自己的小连接迭代器,例如:顺序地,迭代它所拥有的迭代器,或者使用Guava的Iterator.concat(),它将“将多个迭代器组合成一个迭代器”。无论哪种方式,您都不必复制任何数据。

答案 1 :(得分:0)

我不会调用一个名称类似于它的类型的变量(可能会改变),但是它会包含什么:

ArrayList<Student> students = new ArrayList<Student>();

我会将addStudent方法更改为接受Student,而不是名称,姓氏和年龄。

  public void addStudent(Student newStudent) 
  {
          students.add(newStudent);
  }

然后您可以添加以下学生:

class1.addStudent(new Student("jennifer", "lopez", 30));

但是也要将同一个学生添加到不同的班级:

Student jennifer = new Student("jennifer", "lopez", 30);
class1.addStudent(jennifer);
class2.addStudent(jennifer);

最后,是的,你需要在循环中使用两个迭代器:)

答案 2 :(得分:0)

你的设计完全错了。您不应为每个(学校)ClassRoom创建两个不同的(Java)类。只需创建一个:

public class ClassRoom
{
    ... all your stuff here

    public void addStudent(Student st)
    {
        students.add(st);
    }

    public List<Student> getStudents()
    {
        return students;
    }
}

然后你可以像这样创建多个类并将它们放在一个数组中:

List<ClassRoom> rooms = new ArrayList<ClassRoom>();

ClassRoom room1 = new ClassRoom("5 Latin Sience");
room1.addStudent(new Student("Anna", "Bell", 12));
room1.addStudent(new Student("Martin", "Foo", 12));
room1.addStudent(new Student("Stef", "Bar", 12));


ClassRoom room2 = new ClassRoom("4 Maths");
room2.addStudent(new Student("Anna", "Bell", 11));
room2.addStudent(new Student("Martin", "Foo", 11));
room2.addStudent(new Student("Stef", "Bar", 15));

// put them int the array.
rooms.add(room1);
rooms.add(room2);

现在,您可以遍历每个教室,然后使用嵌套for循环遍历每个学生:

for (ClassRoom room : rooms)
{
    for (Student st : room.getStudents())
    {
        System.out.println(... student details here ...);
    }
}

答案 3 :(得分:0)

我同意关于糟糕设计的答案,但要回答实际问题,请为两个列表获取一个迭代器,下面的代码应该可行。由于阵列复制,这将是计算上的昂贵,因此您可能希望使用链接列表来缓解这种情况。

clrm1.getStudents().clone().addAll(clrm2.getStudents()).iterator();

另一种选择是使用带有学生列表的Class对象列表,然后使用flattening iterator

答案 4 :(得分:0)

我没有看到两个教室的不同课程的原因:它们是相同的。

public class Classroom {
  // each classroom has a list of students
  List<Student> students = new ArrayList<Student>();

  // each classroom has a method to add a new student
  public void addStudent(String name, String lastName, int age) {
    Student st = new Student(name, lastName, age);
    al.add(st);
  }

  // each classroom has a method to "show" his students
  public List<Student> getStudents() {
    return students;
  }
}

现在你有一台机器

public class Machine{

    // a list of classrooms
    List<Classroom> classRooms = new ArrayList<Classroom>();

    // just to start the application
    public static void main(String[] args){
        Machine machine = new Machine();
        machine.printStudents();
    }

    public Machine() {
      // we initialize the classrooms
      // Note - a machine wouldn't create classes, this is just for the demo
      Classroom class1 = new Classroom();
      class1.addStudent("Michael", "Smith", 12);
      class1.addStudent("Jennifer", "Lopez", 13);
      classRooms.add(class1);

      Classroom class2 = new Classroom();
      class2.addStudent("Brian", "Con", 15);
      class2.addStudent("Brian", "Con", 15);          
      classRooms.add(class2);
    }

    void printStudents() {
      for (Classroom class:classrooms) {
        // one could print the classname at this place
        for (Student student: class.getStudents()) {
          System.out.println("\nName: " + st.getName() + "\nLast name: " + st.getLastName() + "\nAge: " + st.getAge());
        }
      }
    }
}

这与您的解决方案完全不同 - 只有一个类用于教室而没有迭代器(我们不需要它们)。试一试,并将其与您的代码进行比较。