Как изменить объекты в списке <? расширяет MyObject> во время итерации? - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь изменить поле в выбранных объектах в Списке, но я не могу найти способ сделать это, используя обычный Iterator, потому что у него нет метода set().

Я пытался использовать ArrayListIterator, который предоставляет метод set(), но это вызывает исключение приведения. Есть ли способ обойти это?

   Iterator it = topContainer.subList.iterator();
   while (it.hasNext()) {
      MyObject curObj = (MyObject) it.next();
      if ( !curObj.getLabel().contains("/") ) {
           String newLabel = curObj.getLabel() + "/";
           curObj.setLabel(newLabel);
           ((ArrayListIterator) it).set(curObj)
       }
    }

Я ожидаю, что исходный текущий объект в списке будет установлен без инцидентов, но вместо этого я получаю это исключение:

java.util.ArrayList $ itr не может быть приведен к org.apache.commons.collections.iterators.ArrayListIterator

Как правильно выполнить то, что я хотел бы сделать?

Ответы [ 3 ]

0 голосов
/ 11 января 2019

Правильный путь будет следующим (работает не для версий Java ниже 1.5):

for(MyObject curObj : topContainer.subList){
    if (!curObj.getLabel().contains("/")) {
       String newLabel = curObj.getLabel() + "/";
       curObj.setLabel(newLabel);
    }
}

Это расширенный цикл for, он тоже вызывает итератор, но вы его не видите.

Также установка объекта через итератор не требуется, так как вы работаете со ссылками на Object s в Java, когда вы редактируете объект, все, у кого есть указатель на этот объект, тоже увидят это изменение. Более подробно вы можете прочитать этот великий пост: Является ли Java «передачей по ссылке» или «передачей по значению»?

Если вы не можете использовать Java 5, значит, вы упускаете большие возможности. Текущая версия Java 11 . Так что вам действительно нужно обновить JDK

0 голосов
/ 11 января 2019

Вы просто должны установить метку. В JAVA 11 вы можете использовать потоки. это делает ваш код более читабельным.

List<MyObject> list = topContainer.subList;
list
    .stream()
    .filter(Predicate.not(e->e.getLabel().contains("/")))
    .forEach(e->e.setLabel(e.getLabel()+"/"));

В Java 8 вы можете использовать

(!e->e.getLabel().contains("/"))

вместо

Predicate.not(e->e.getLabel().contains("/")

0 голосов
/ 11 января 2019

Вам вообще не нужно звонить set. Вы можете просто позвонить setLabel на curObj:

// please, don't use raw types!
Iterator<? extends MyObject> it = topContainer.subList.iterator();
while (it.hasNext()) {
   MyObject curObj = it.next();
   if ( !curObj.getLabel().contains("/") ) {
       String newLabel = curObj.getLabel() + "/";
       curObj.setLabel(newLabel);
   }
}
...