Java Forum / General / December 2005
mono-thread concurrent modification
jpprost@gmail.com - 29 Nov 2005 06:12 GMT Hi,
I can't find an implementation of Collection which would let me legally add new elements to the very list I iterate on. Let me re-phrase: I want to iterate on an array/list (or whatever structure which is Collection-compatible) and in the meantime add new elements to this list (say at the end), so that they are taken into account in the iteration process. It's important to emphasize that I only need to add new elements--no removal is required. - A SynchronizedList doesn't help here, since my application is mono-thread--and anyway even when faking a synchronized section I still get a ConcurrentModificationException. - I thought a ListIterator with a LinkedList would be the solution, but no: I still get the same exception--though in theory I don't see the problem: I should be allowed to add new elements at the end of a linked list on which I iterate, shouldn't I?...
Do I really have to implement something myself, or should I have a better look somewhere?
Cheers,
-- Jean-Philippe Prost [E6A 341, x9542] Centre for Language Technology Macquarie University ~ Sydney, Australia <http://www.ics.mq.edu.au/~jpprost/> _______________________________________________
Roedy Green - 29 Nov 2005 06:24 GMT >Let me re-phrase: I >want to iterate on an array/list (or whatever structure which is >Collection-compatible) and in the meantime add new elements to this >list (say at the end), look at the methods of Iterator.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Roedy Green - 29 Nov 2005 06:27 GMT On Tue, 29 Nov 2005 06:24:09 GMT, Roedy Green <my_email_is_posted_on_my_website@munged.invalid> wrote, quoted or indirectly quoted someone who said :
>look at the methods of Iterator. sorry ListIterator.add. It inserts at the spot you are working on.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
jpprost@gmail.com - 29 Nov 2005 06:34 GMT Yes, that's what I thought but for some reason I still get the same exception.
-- Jean-Philippe Prost [E6A 341, x9542] Centre for Language Technology Macquarie University ~ Sydney, Australia <http://www.ics.mq.edu.au/~jpprost/> _______________________________________________
zero - 29 Nov 2005 10:52 GMT jpprost@gmail.com wrote in news:1133246093.516969.140790 @g49g2000cwa.googlegroups.com:
> Yes, that's what I thought but for some reason I still get the same > exception. What's the exact exception, and the code that produces it - would be helpful if we could see the actual line that throws the exception, and some code leading up to it.
 Signature Beware the False Authority Syndrome
Mike Schilling - 29 Nov 2005 13:34 GMT > Yes, that's what I thought but for some reason I still get the same > exception. You need to to the add using the iterator; any change to the List "behind the iterator's back" causes the ConcurrentChangeException.
jpprost@gmail.com - 29 Nov 2005 23:28 GMT [catching up late, thanks to the time zones!]
> You need to to the add using the iterator; any change to the List "behind > the iterator's back" causes the ConcurrentChangeException. Yes, maybe I wasn't clear in my messages but that's exactly what I meant: I did try the ListIterator, with the add() method that comes with it (rather than the one from the Collection) and yet I still get the ConcurrentModificationException.
As for the other suggestions: - Yes, there's a big performance issue--as the module is involved in a big combinatorial decision problem--, so indeed my first choice is to go for an ArrayList. I just mentioned the LinkedList because I think what I want should be possible at least with that kind of structure, where the dynamic changes are a main motivation for it.
- I also agree that the good old "do-it-yourself" solution, with a simple array and an integer index that I would manage myself is probably what I'll end up adopting. I just thought there would be a nice-and-neat implementation out there, which would embed everything in a Collection-like kind of solution with iterator and everything, that you can use as a black box. But now it looks like there is nothing available, really. Never mind, I'll go for the "old fashion" way ;-)
-- Jean-Philippe Prost [E6A 341, x9542] Centre for Language Technology Macquarie University ~ Sydney, Australia <http://www.ics.mq.edu.au/~jpprost/> _______________________________________________
Mike Schilling - 29 Nov 2005 06:28 GMT > Hi, > [quoted text clipped - 5 lines] > iteration process. It's important to emphasize that I only need to add > new elements--no removal is required. If it's a list, why not just use an integer index to step through it; this works fine when elements are added to the end. Just remember to compare it to the current size() rather than the size() when the iteration started.
LaieTechie - 29 Nov 2005 07:32 GMT > If it's a list, why not just use an integer index to step through it; this > works fine when elements are added to the end. Just remember to compare > it to the current size() rather than the size() when the iteration > started. If it's a LinkedList, then by supplying an index, it has to walk from the beginning - not very efficient.
Laie Techie
Chris Uppal - 29 Nov 2005 10:56 GMT > If it's a list, why not just use an integer index to step through it; this > works fine when elements are added to the end. Just remember to compare > it to the current size() rather than the size() when the iteration > started. And also remember to change the LinkedList (as in the OP's experiment) back to an ArrayList !
-- chris
Mike Schilling - 29 Nov 2005 13:32 GMT >> If it's a list, why not just use an integer index to step through it; >> this [quoted text clipped - 5 lines] > back to > an ArrayList ! Only if performance is an issue :-)
To be honest, I'm not sure why a LinkedList isn't a LinkedCollection, since performing random-access operations on one is a bad idea. (Or conversely, why there isn't a RandomAcesssList interface that adds those methods, while List merely adds the listIterator() method).
Chris Uppal - 29 Nov 2005 15:04 GMT > To be honest, I'm not sure why a LinkedList isn't a LinkedCollection, By "LinkedCollection" do you mean "Collection" ? If so then I don't see a good reason either.
-- chris
Mike Schilling - 29 Nov 2005 18:49 GMT >> To be honest, I'm not sure why a LinkedList isn't a LinkedCollection, > > By "LinkedCollection" do you mean "Collection" ? If so then I don't see a > good > reason either. Isn't *called* LikedCollection, I meant to type. (By implication, implements Collection but not List.)
Thomas Hawtin - 29 Nov 2005 16:44 GMT > To be honest, I'm not sure why a LinkedList isn't a LinkedCollection, since > performing random-access operations on one is a bad idea. (Or conversely, > why there isn't a RandomAcesssList interface that adds those methods, while > List merely adds the listIterator() method). Discriminating on the basis of immutability would come higher on my list. It seems that the decision was made to have few interfaces for collections, rather than have every possible combination.
Most uses of Lists are random access, so the names should go something like List extends SeriallyAccessibleList. Even then an internal implementation of get(int) would 'normally' be faster than an iterator implementation, and also be easier to fit other optimisations to.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Mike Schilling - 29 Nov 2005 18:55 GMT >> To be honest, I'm not sure why a LinkedList isn't a LinkedCollection, >> since performing random-access operations on one is a bad idea. (Or [quoted text clipped - 9 lines] > implementation of get(int) would 'normally' be faster than an iterator > implementation, and also be easier to fit other optimisations to. Suppose you're writing a method to process an arbitrary List. As things are, it's very wrong to write:
void processList(List l) { for (int i = 0; i < l.size(); i++) { Object member = l.get(i); ... } }
since the performance could be horrific for a large LinkedList. It must be written as
void processist(List l) { for (Iterator iter = l.iterator(); !iter.hasNext(); ) { Object member = l.next(); ... } }
Since the random access get() shouldn't be used on arbitrary lists, why is it defined in the List interface?
Thomas Hawtin - 29 Nov 2005 20:08 GMT >>Discriminating on the basis of immutability would come higher on my list. >>It seems that the decision was made to have few interfaces for [quoted text clipped - 16 lines] > } > } That's not "wrong". It might give you poor performance in unusual cases, but so might many things. It would be more "wrong" to call add on a List of unknown parentage, but we are happy to do that all the time.
> since the performance could be horrific for a large LinkedList. It must be > written as There is no must about it. Indeed java.util.Collections takes a smarter, adaptive approach.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Mike Schilling - 30 Nov 2005 01:42 GMT >>>Discriminating on the basis of immutability would come higher on my list. >>>It seems that the decision was made to have few interfaces for [quoted text clipped - 26 lines] > There is no must about it. Indeed java.util.Collections takes a smarter, > adaptive approach. Based on what?
Thomas Hawtin - 30 Nov 2005 09:07 GMT >>>since the performance could be horrific for a large LinkedList. It must >>>be written as [quoted text clipped - 3 lines] > > Based on what? Implementation of java.util.RandomAccess and size.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Mike Schilling - 30 Nov 2005 06:45 GMT >> Suppose you're writing a method to process an arbitrary List. As things >> are, it's very wrong to write: [quoted text clipped - 9 lines] > > That's not "wrong". It might give you poor performance in unusual cases, Is LinkedList an unusual case?
> but so might many things. It would be more "wrong" to call add on a List > of unknown parentage, but we are happy to do that all the time. At least that throws an obvious exception, rather than silently being a performance problem.
Thomas Hawtin - 30 Nov 2005 09:07 GMT >>That's not "wrong". It might give you poor performance in unusual cases, > > Is LinkedList an unusual case? It should be. Else you've done it wrong.
>>but so might many things. It would be more "wrong" to call add on a List >>of unknown parentage, but we are happy to do that all the time. > > At least that throws an obvious exception, rather than silently being a > performance problem. I'd be much more happy going into production with something that wasn't heavily optimised than something that stopped working.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Mike Schilling - 30 Nov 2005 18:34 GMT >>>That's not "wrong". It might give you poor performance in unusual cases, >> [quoted text clipped - 10 lines] > I'd be much more happy going into production with something that wasn't > heavily optimised than something that stopped working. Normal unit testing will find the exception, but not the performance problem.
Chris Uppal - 30 Nov 2005 09:17 GMT > That's not "wrong". It might give you poor performance in unusual cases, > but so might many things. What is /wrong/ IMO is not calling get(int) on a LinkedList, but that LinkedList advertises itself as /suitable/ for (routinely) calling get(int). I see no reason why LinkedList shouldn't have a get(int) method -- although a better name might be searchForItemAtIndex(int) -- but that doesn't mean that it should present itself as interchangable (in this respect) with an ArrayList.
Put it this way, are there any circumstances where it is appropriate to use get(int) on a LinkedList without knowing that it /is/ a LinkedList ?
The contract implied by an interface doesn't stop at the subtype relationship -- it is not enough simply to provide methods with the expected signatures, they should also behave as expected.
public class XList<E> implements List<E> { //... routine stuff
E get(int i) { System.exit(i); }
//... more routine stuff }
In what useful sense is that a List over and above being a Collection ?
-- chris
Chris Uppal - 30 Nov 2005 11:58 GMT > There is no must about it. Indeed java.util.Collections takes a smarter, > adaptive approach. To my mind, the use of the RandomAccess marker in Collections is better characterised as indefensible switch-on-type than good programming. Same goes for java.util.AbstractList.subList(int, int) -- which is the /only/ other place where that marker interface is used[*] in the entire 1.5 JRE.
-- chris
([*] as the target of an instanceof or checkcast bytecode)
Mike Schilling - 30 Nov 2005 18:33 GMT >> There is no must about it. Indeed java.util.Collections takes a smarter, >> adaptive approach. [quoted text clipped - 5 lines] > place > where that marker interface is used[*] in the entire 1.5 JRE. I presume that RandomAccess is new for 1.5; I was unaware of it. It makes much less sense as a marker interface than as the place where get() etc. are defined.
Thomas Hawtin - 30 Nov 2005 19:08 GMT > I presume that RandomAccess is new for 1.5; I was unaware of it. It makes > much less sense as a marker interface than as the place where get() etc. are > defined. No, it was in 1.4.
http://java.sun.com/j2se/1.4.2/docs/guide/collections/changes4.html
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
John C. Bollinger - 01 Dec 2005 02:16 GMT > Most uses of Lists are random access, The vast majority of *my* uses of Lists are serial access. It is quite rare that I both want some element in the middle of a List and also know its index. The most common exception is sorting, but I don't do that often. On the other hand, ArrayList is the List implementation I usually use, whether I anticipate random access or not.
 Signature John Bollinger jobollin@indiana.edu
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|