Как итератор работает с конструктором

Привет, я новичок в Java, и я только что столкнулся со следующей проблемой в домашнем задании. Мне нужно написать класс, который добавляет новый объект в список при вызове метода void. В качестве подсказки дана структура метода итератора, поэтому основная структура моего кода теперь выглядит так:

public class objectList implements Iterable<Obj> {

  private ArrayList<Obj> objectList;
  attribute_a A;
  attribute_b B;
  attribute_c C;


  public objectList(attribute_a A, attribute_b B, attribute_c C){
      objectList = new ArrayList<Obj>;
      this.A = A;
      this.B = B;
      this.C = C;
  }

  public void extendList(attribute_a A, attribute_b B, attribute_c C){
      objectList.add(new Obj(A,B,C));
  }

  public Iterator<Obj> iterator(){
      return objectList.iterator();
  }

  @Override
  public String toString(){
      newstr = "";
      for(i = 0;i<objectList.size();i++)
      {
        //Assuming Obj has the method toString()
        //It prints out all details of each object, then join into one string
        newstr += objectList.get(i).toString();
      }
      return newstr;
  }
}

Мне сказали просто использовать java.util.iterator, а не пользовательский итератор, поэтому он избавил меня от определения HasNext(), next(), remove() и т. д.

Редактировать: моя цель - иметь возможность печатать объекты, хранящиеся в objectList, после того, как extendList() вызывается несколько раз, т.е. в списке хранится много элементов. Теперь я могу распечатать только последний элемент в нем (в списке только 1 элемент).

Что мне нужно сделать, чтобы «курсор» автоматически указывал на следующий элемент -> получить атрибут -> выполнять задачи для атрибута -> следующий элемент и т. д., пока список не будет завершен?


person user3531101    schedule 14.04.2014    source источник
comment
Вы говорите, что можете распечатать только последний объект, а не все добавленные объекты? Это ваша проблема?   -  person RKC    schedule 14.04.2014
comment
Каков ваш вывод toString?   -  person Jakub H    schedule 14.04.2014
comment
Пожалуйста, дайте свою цель или определение вашей проблемы (чего вы хотите достичь?)   -  person niiraj874u    schedule 14.04.2014


Ответы (2)


Давайте посмотрим, что здесь происходит...

Итак, у вас есть класс, и в нем есть поле с именем objectList. Когда вы создаете экземпляр new objectList, вызывается конструктор, и поле инициализируется пустым списком. Все идет нормально. (Однако, почему у вас есть поля с именами A, B и C? Кажется, что они вообще не используются, поэтому кажется запутанным требование, чтобы кто-то передал вашему конструктору три параметра, которые фактически игнорируются.)

Затем всякий раз, когда вызывается extendList, в список экземпляра добавляется новый Obj. Это выглядит правильно. Это означает, что в любой момент мы можем сказать, что размер objectList равен количеству вызовов extendList для этого объекта.

Точно так же вызов iterator просто вернет стандартный итератор Java для этого списка. Таким образом, итератор должен посетить каждый Obj в этом списке, который будет числом элементов, равным количеству вызовов extendList для одного и того же объекта objectList.

Итак, почему это не работает?

Это не ясно из кода, который вы опубликовали. Сам ваш класс выглядит нормально, поэтому вывод состоит в том, что вы, должно быть, неправильно его называете. Я предполагаю, что на самом деле вы создаете несколько экземпляров класса — каждый раз, когда вы вызываете конструктор, вы создаете новый экземпляр с другими полями. Например, это не будет делать то, что вы ожидаете:

new objectList().extendList("A1", "B1", "C1");
new objectList().extendList("A2", "B2", "C2");
new objectList().extendList("A3", "B3", "C3");
return new objectList().iterator();

потому что каждый раз создается новый экземпляр, эффективно отбрасывая состояние от предыдущего. Вы бы хотели переписать это как:

objectList ol = new objectList();
ol.extendList("A1", "B1", "C1");
ol.extendList("A2", "B2", "C2");
ol.extendList("A3", "B3", "C3");
return ol.iterator();

Если это не решит проблему, посмотрите, как вы используете класс, посчитайте, сколько раз вы вызываете extendList в том же экземпляре, из которого вы получаете итератор. Если вы сомневаетесь - заставьте Java считать за вас - добавьте System.out.println("in extendList") вызовов (и, возможно, некоторые в конструкторе), чтобы увидеть, что и когда вызывается. На самом деле, если есть опасения, что используются разные экземпляры класса, вы можете получить уникальный идентификатор для конкретного экземпляра с помощью System.identityHashcode(), например:

 public void extendList(attribute_a A, attribute_b B, attribute_c C){
    System.out.println("Extending list for " + System.identityHashcode() + " with " + A + ", " + B + ", " + C);
    objectList.add(new Obj(A,B,C));
 }

В противном случае, возможно, стоит ознакомиться с тем, как использовать отладчик, и последовательно выполнять вашу программу. Это позволит вам видеть состояние вашей программы на каждом шагу и, надеюсь, даст вам понять, где что-то начинает расходиться с вашими ожиданиями.


(Я также рекомендую вам использовать стандартные соглашения об именах Java, так как ваш код на удивление сложно читать без них в данный момент. Имена классов должны начинаться с заглавных букв (и быть в UpperCamelCase). Имена переменных и полей должны начинаться со строчных букв. буквы (и быть в нижнем верблюжьем регистре). На данный момент имя вашего класса выглядит как переменная, а ваши поля - как общие параметры. new objectList() просто выглядит неправильно!)

person Andrzej Doyle    schedule 14.04.2014
comment
Спасибо за подробный ответ! Методы вызываются заданным тестовым файлом, в который он входит: ol.extendList(A,B,C) дважды и пытается сопоставить результат toString() с ожидаемой строкой. Сейчас я собираюсь больше узнать о стандартных соглашениях и конструкторах. Ваше здоровье! - person user3531101; 14.04.2014

Попробуйте инициализировать этот objectList = new ArrayList<Obj>; вне конструктора,

private ArrayList<Obj> objectList=new ArrayList<Obj>();
person RKC    schedule 14.04.2014
comment
Помимо того факта, что не очень ясно, какая проблема у OP, технически нет реальной разницы между инициализацией поля списка в точке объявления или в качестве первого оператора в конструкторе. Хотя согласен, что лучше. Но этот ответ никоим образом не поможет ОП с его (еще предстоит лучше объяснить) проблемой. - person Seelenvirtuose; 14.04.2014