I know that, casting is not the correct word when
java.lang.Object
-> java.util.concurrent.CopyOnWriteArrayList<E>
and
java.lang.Object
-> java.util.AbstractCollection<E>
-> java.util.AbstractList<E>
-> java.util.ArrayList<E>
But what I want is adding the behavior of the CopyOnWriteArrayList to the ArrayList.
Eg :
I want to do following. But tstArry is an ArrayList. not a CopyOnWriteArrayList
for(TestCls testCls : tstArry)
if(testCls.getVal1().equals("a1"))
tstArry.remove(testCls);
Or is this the only way to get the job done?
for(int i = 0; i < tstArry.size(); i++)
if(tstArry.get(i).getVal1().equals("a1"))
tstArry.remove(i--);
tstArry is an ArrayList from a class that I haven't had the control on it. So, Please make the changing the type of ArrayList to another is the far most solution.
You can't remove() from iterated collection when using the enhanced for-each loop. The for-each loop uses Iterator<TestCls> implicitly. The JavaDoc clearly states that
The iterators returned by this class's
iterator()andlistIterator()methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's ownremove()oradd()methods, the iterator will throw aConcurrentModificationException.
The for-each loop creates an iterator internally and uses it to traverse the list. Then you change the structure of the list ... and the iterator has to fail. The thing is that you don't have access to the iterators methods, so you have to use Iterator<TestCls> explicitly. The generated traversing bytecode will be the same, the only difference being you being able to remove elements from the list as traverse it.
for (Iterator<TestCls> iter = tstArry.iterator(); iter.hasNext(); ) {
TextCls testCls = iter.next();
if(testCls.getVal1().equals("a1")) {
iter.remove();
}
}
Clarifying EDIT as you are obviously not familiar with iterators and their function. From the Oracle tutorial on Collections:
An
Iteratoris an object that enables you to traverse through a collection and to remove elements from the collection selectively, if desired. You get anIteratorfor a collection by calling itsiterator()method.Note that
Iterator.remove()is the only safe way to modify a collection during iteration; the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.Use
Iteratorinstead of thefor-eachconstruct when you need to:
- Remove the current element. The
for-eachconstruct hides the iterator, so you cannot callremove(). Therefore, thefor-eachconstruct is not usable for filtering.
The key is Effective Java, Item 39: Make defensive copies when needed
Take the list you get from the other class. Make a copy of it:
List<TestCls> myCopy = new ArrayList<>(theOtherList);
Then remove the unwanted elements from your copy, not the original collection. To do this, you'll need to use the Iterator.remove() method.
Or you use a library like Guava that lets you filter a collection using predicates:
Predicate<TestCls> predicate = new Predicate<TestCls>(){
public boolean apply(TestCls data){
// add check here
}
};
List<TestCls> myList =
FluentIterable.from(theOtherList).filter(predicate).toList();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With