How to modify objects in a List<? extends MyObject> while iterating?

11
January 12, 2019, at 3:10 PM

I am trying to modify a field in select objects in a List but I am unable to find a way to do so, using plain Iterator because it has no set() method.

I tried using ArrayListIterator that provides a set() method, but this throws a casting exception. Is there way to workaround this?

   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)
       }
    }

I expect the original current object in the list to be set without incident, but instead I am getting this exception:

java.util.ArrayList$itr cannot be cast to org.apache.commons.collections.iterators.ArrayListIterator

What is the proper way of accomplishing what I would like to do?

Answer 1

You do not need to call set at all. You can just call setLabel on 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);
   }
}
Answer 2

The correct way would be following (works not for java versions below 1.5):

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

This is an enhanced for-loop, and it does call the iterator too, but you can't see it.

Also setting the object via the iterator is not needed, as you're working with references to Objects in Java, when you edit an object, everyone that has a pointer to that object, will see the change too. For more you can read this great post: Is Java “pass-by-reference” or “pass-by-value”?

If you can't use Java 5, then you're missing out big time. The current java version is 11. So you should really, really, really, upgrade your JDK

Answer 3

you just have to set the label. In JAVA 11 you can use streams. it makes your code more readable.

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

In java 8 you can use

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

instead of

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

READ ALSO
Java Spring-boot: Problem to finde resources

Java Spring-boot: Problem to finde resources

I have a Spring-boot backend Angular front end applicationThe application runs well if it is run on port 4200 (Running frontend from the front end)

14
Override Dashboard in TYPO3

Override Dashboard in TYPO3

Im trying to override the help_AboutmodulesAboutmodulesiframe in TYPO3I think that is the initial page when you are log in as backend user

17
Visual form builder Is this plugin compatible with Amazon S3/Cloudfront?

Visual form builder Is this plugin compatible with Amazon S3/Cloudfront?

I am using vusual form builder for one of my WordPress siteVisual form builder this plugin compatible with Amazon S3/Cloudfront? The upload function is storing the files on our S3 server correctly but the link to the file in the "Entries" section is pointing...

18