• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

style issue(maybe performance, too)

 
Ranch Hand
Posts: 280
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My colleague and I are discussing which is better Java style--using the Iterator object in a "for" loop or using the normal int counting mechanism. Does it just depend on the context(like running through a Collection or the indices of an array) or is there a cut and dry answer?


------------------
Jason R. Kretzer
Software Engineer
http://alia.iwarp.com
 
Ranch Hand
Posts: 149
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am not sure about performance but for what it's worth ... I would think the approach would depend on the context.
For example, if you are iterating through some Collection I would think that you would want to obtain an Iterator and use a while loop.
ex. while( myIterator.hasNext() ) { //do some stuff }
If the number of passes you wish to make is fixed by some means (set by a variable, input or always the the same number of passes) then I would probably use a for loop with a counter.
ex. for( int i = 0; i < numberPasses; i++ ) { //do some stuff }
Also, I think the intent would be more obivous to someone reading through the code.
 
Ranch Hand
Posts: 547
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi,
i think Iterator and Enumerations are slower than for loop with the count of objects and a getElementAt(int)-like method call. BUT ,again i think, it is way better to use them. with this you hide the way you implemented your stuff. if you ever hgave to change the type of collection used, then you can still use iterator as before (ok, this will not happen to often, agreed).
so i think it is better design to use the iterators.

pascal
 
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Standard consultant's answer: "It depends..."
What is the context? In general, I would say that programming to an interface is better. The Iterator interface was introduced as an alternative to the Enumerator interface so I guess I would prefer the former. If, however, this question is in the context of performance tuning, Peter Haggar, in his book "Practical Java", advises:

  1. Do not use an Enumeration or an Iterator to traverse a Vector
  2. Prefer an array to a Vector or ArrayList

  3. Also, use a profiler to identify the bottlenecks in your code.
    As for style, I go with the while (iterator.hasNext()) {} construct because it's clearer to me. The for (Iterator i = col.iterator(); i.hasNext(); ) may seem more clever but I think less experienced maintenance programmers will appreciate the clarity of the while() construct more.
    My 2 cents,
    Junilu

    [This message has been edited by JUNILU LACAR (edited December 19, 2001).]
 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It is much faster for the cpu to increment a counter and make a comparison (is the counter greater than 5?) than it is to make a method call (reference a different place in memory and execute a line or two of code) and then make a comparison. Though I have to agree that code is clearer by using an iterator.
Jeff
 
Jason Kretzer
Ranch Hand
Posts: 280
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So, the consensus is to go by context. If using collections, then implement an Iterator. If using a Vector/array, then use the counter.
I can definitely see why the int counter would be faster though. After all, it has to execute a method in order to increment as opposed to just incrementing an int. Much fewer memory references.
Thanks everyone.

------------------
Jason R. Kretzer
Software Engineer
http://alia.iwarp.com
 
whippersnapper
Posts: 1843
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by JUNILU LACAR:
As for style, I go with the while (iterator.hasNext()) {} construct because it's clearer to me. The for (Iterator i = col.iterator(); i.hasNext(); ) may seem more clever but I think less experienced maintenance programmers will appreciate the clarity of the while() construct more.


But you left out the key part of the while construct:
Iterator iterator = collection.iterator() ;
The while construct exposes the identifier "iterator" to a larger scope than necessary. That's why I tend to prefer the for construct.
 
Ranch Hand
Posts: 82
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Interesting Post.
In my opinion, performance wise the normal counter is fast. No doubts. However, when it comes to writing reusable/extensible code, Iterator comes into picture, and afterall thats what is OO development is all about.
consider this,

At first look, this class looks perfectly fine and also looks well encapsulated(?). It doesn't expose its private varible( as its private). Clients of this class don't know the name of the private variable(videos), as a result if the variable name is changed clients won't be affected. so, it seems like its well encapsulated. However, if we take a closer look at the code, we realize that we are returning a Vector in the getVideos() function, which goes to say that our collection is implemented as a Vector. Clients of this class know that the collection is implemented as vector and write their code such that they expect a return value of type vector. Now if the writer of this class decides to change the collection from a Vector to something else(ex: stack,queue, array ..anything for that matter), then he should be able to do so without affecting his clients(Thats what is encapsulationg afterall). However, we see that if he changes his collection type then he needs to change the return type of the getVideos(), which means his clients will be affected.
(Well, it is surely possible to return a vector even when the collection is implemented as an array/stack/queue , etc..but that is not the best way to code afterall. Why would anyone implement something as a stack/queue and convert it to vector just for returning)
Therefore, we see that we need a way in which we should have the liberty to change the type of collection we use, but at the same time make sure our clients are not affected. Well, this is where Iterators come into picture.
If we return an iterator instead of a Vector(as in the code above) then (i) our clients don't know what type of collection we are using to store our videos, which is good , because thats what is real encapsulation. (ii) we are at liberty to change our type of collection without affecting our clients code, because all collections support the interator interface.
so, in short, its not style, but a good programming practice to return an iterator, if you want your code to be extensible.
Performance..well, it surely will go down a little bit. But then everything comes with a price, and this price is sure worth the benefit it gives.
Rex

 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Note that if your List is actually a LinkedList, then using get(int) in a loop is a very bad idea, leading to quadratic behavior. When you say get(500), the LinkedList will start at 0 and follow each link up to 500 to get the item you want. When you say get(501) it will again start at 0,and waste a lot of time. A linked list is not designed for random access - the get(int) method is a random access which you're trying to use sequentially, but the API has no way of knowing you're using it sequentially, so the performance sucks. Much better to use the Iterator, which does imply sequential access, which means the LinkedList iterator knows to save a reference to the last element accessed, which means it's trivial to get the next element in one step.
I look at it this way - if you use an Iterator in a case where get(int) access is faster, you'll lose a little bit of time, but it's a nice constant factor, and it's very small. If you use get(int) when an Iterator is called for, you can get quadratic behavior instead of linear, which is far worse. So, unless you're sure of what you're doing (and sure that your ArrayList or Array will never be replaced by a LinkedList), then just use the Iterator.
 
Jason Kretzer
Ranch Hand
Posts: 280
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That is a good point Rex. I had never really thought about or tried returning an Iterator like that. It would certainly make a class more robust and reusable. It could probably add to readability of code as well since you don't need to know what kind of collection it is. You just need to use the Iterator methods to access the data. It kind of puts you on higher level of coding--you don't need to know what it really is just whether it has more elements.
Interesting technique.

------------------
Jason R. Kretzer
Software Engineer
http://alia.iwarp.com
 
Rex Rock
Ranch Hand
Posts: 82
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thats right Jason. By returning an iterator, we are making our clients to work at higher level of abstraction, which is good, because we can change our implementation without affecting our clients. Abstraction, afterall is a key concept in OO Development.
Rex
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Michael Matola:
The while construct exposes the identifier "iterator" to a larger scope than necessary. That's why I tend to prefer the for construct.


True, the iterator is still visible outside of where it is used and this may be an issue if your methods are large and do a lot of things. In well-factored and cohesive code, however, this is pretty much a non-issue. Again, it is just a matter of style and clarity. I just happen to think that the while construct is clearer. YMMV.
Junilu
 
Ranch Hand
Posts: 1365
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'd just like note that while an Iterator of a LinkedList is faster than a for loop as Jim said, and Iterator of an ArrayList is faster than one for a LinkedList. Sequential access to linked lists is a side effect, not a feature -- the real benifit is the ability to add things to the middle without reallocating an array.
 
reply
    Bookmark Topic Watch Topic
  • New Topic