Results 1 to 9 of 9

Thread: Iterators in Java

  1. #1
    Join Date
    Mar 2011
    Location
    South Africa
    Beans
    137
    Distro
    Kubuntu 11.10 Oneiric Ocelot

    Iterators in Java

    Hi all

    I've recently started using iterators to traverse LinkedLists in java. I've got the following code:
    Code:
           LinkedList <Features> features = new LinkedList();
           //some code
    
            Iterator it = features.iterator();
            while(it.hasNext()){
                System.out.println(it.next().printFeature());
            }
    and I'm not sure what's wrong here. printFeature() is a method in the Features class. I thought that the the "it" variable would be a placeholder for each of the elements in my LinkedList. Alas, I cannot call the printFeature() method.
    boink.

  2. #2
    Join Date
    Apr 2005
    Location
    Hampshire, UK
    Beans
    1,274

    Re: Iterators in Java

    Untested, but you probably want:

    Code:
           LinkedList <Features> features = new LinkedList();
           //some code
    
            Iterator<Features> it = features.iterator();
            while(it.hasNext()){
                System.out.println(it.next().printFeature());
            }
    (based on this.)

    Edit:

    Actually, you might be able to just do the much cleaner:

    Code:
           LinkedList <Features> features = new LinkedList();
           //some code
    
           for(Features feature : features) 
           {
                System.out.println(feature.printFeature());
           }
    Last edited by GeneralZod; March 19th, 2012 at 11:28 AM.

  3. #3
    Join Date
    May 2007
    Location
    Leeds, UK
    Beans
    1,664
    Distro
    Ubuntu 13.10 Saucy Salamander

    Re: Iterators in Java

    I thought pre Java 7 it would be:

    Code:
    LinkedList<Features> features = new LinkedList<Features>()
    and in Java 7, you get to use the "diamond":

    Code:
    LinkedList<Features> features = new LinkedList<>()
    But what is in the Features class? Is it a feature, or is it a list of features, as the name Features suggests? If it's a class that represents a single feature, the singular works out much nicer:

    Code:
    List<Feature> features = new LinkedList<>()
    for (Feature feature : features) {
        System.out.println(feature); // Assuming a toString() method
    }
    Are you sure you want a linked list? ArrayList is usually the more better list implementation unless you have good reasons for using a linked list. In any case, programming to the List interface, rather than a specific implementation, is usually a good idea, as shown above.

    So many questions for such a small piece of code . I'd be interested to see what Features is and what printFeatures() is supposed to do.

  4. #4
    Join Date
    Mar 2010
    Location
    London
    Beans
    924

    Re: Iterators in Java

    While I agree with the other responses hat using Java's enhanced for-loop is the better and cleaner option, I still believe it's good to have an understanding of Iterators. Sometimes you may wish to iterate a structure in a certain way, like every other element or in descending order (using a descendingIterator).

    orrymr, what is the error you're getting exactly?
    I see you're (rightly) using generics to bound the LinkedList to type Features, you should also bound your Iterator to type Features as well, so it knows what types of object it will handle.

    Here is an updated snippet to try, with the change highlighted:

    Code:
    List<Features> features = new LinkedList<Features>();
    //some code
    
    Iterator<Features> it = features.iterator();
    while(it.hasNext()){
        System.out.println(it.next().printFeature());
    }
    Other things to note:
    - The "features" variable is declared to be of type List and not a LinkedList. This gives you much more flexibility like r-senior said, you should always do this and declare types to the most abstract level you can.

    - I have not used Java 7's diamond notation to instantiate the LinkedList. Java 7 is pretty new and I'm not sure on backwards compatibility, or where you will be using this code.
    Last edited by KdotJ; March 19th, 2012 at 03:16 PM.
    - "Make me a coffee..."
    - "No"
    - "sudo make me a coffee"
    - "OK"

  5. #5
    Join Date
    Jan 2010
    Location
    Salem, Oregon
    Beans
    15
    Distro
    Ubuntu 9.10 Karmic Koala

    Re: Iterators in Java

    Java 7 does not seem to have any issues with some of the older code. I installed Java 7 for my CS class and i had no issues even though most of the class was using Java 6. Towards the end of my class our instructor was starting to introduce some new Java 7 concepts, but he was still learning the ins and outs as well.

    I do know that you need users to have 7 installed to run the new code though. That does not seem to be a huge problem if people keep up on the updates.

  6. #6
    Join Date
    Mar 2011
    Location
    South Africa
    Beans
    137
    Distro
    Kubuntu 11.10 Oneiric Ocelot

    Re: Iterators in Java

    Thank you for the responses. My mistake was that I forgot to specify the generic for my Iterator.

    I coded
    Code:
     Iterator it = features.iterator();
    Instead of
    Code:
     Iterator <LinkedList> it = features.iterator();
    Strangely I can implement my LinkedList without the use of the diamond:
    Code:
     LinkedList <Features> features = new LinkedList();
    My reason for using the iterator initially was to remove elements from the LinkedList, if they comply with a certain condition. This didn't work with a normal for(int i = 0; i < features.size(); i++) loop, since as you remove an element the list shrinks.

    Now, for printing out my features, I'm doing the following:
    Code:
    for (Feature feature : features) {
        feature.printFeature(); //should have just made a toString() method
    }
    My Features class was unfortunately poorly named (going to have to change that). It contains one feature only (should have called it Feature). The feature is made up of an array of length 8, and 2 int primitives. I don't know when it would be preferable for me to use an ArrayList over a LinkedList, but I've been using LinkedLists for a while and haven't had any problems with them

    Also, KdotJ, I'm not sure why I'd want to declare my list as the most abstract type available?
    boink.

  7. #7
    Join Date
    Jul 2008
    Location
    England
    Beans
    866

    Re: Iterators in Java

    By declaring it as a list instead of a linked list, if you wanted to change the type in the future, you would only have to change the initialisation of the variable.

    This is useful if you are planning on returning the feature list or passing it into a function as an argument. When you do these things, the function is expecting a type. If you specify the type is LinkedList, you have to change all these references from LinkedList to ArrayList if you decide that an ArrayList is better. If you keep everything to be List, you only need to worry about changing the initialisation of the list.

    Paul

  8. #8
    Join Date
    May 2007
    Location
    Leeds, UK
    Beans
    1,664
    Distro
    Ubuntu 13.10 Saucy Salamander

    Re: Iterators in Java

    Quote Originally Posted by orrymr View Post
    I don't know when it would be preferable for me to use an ArrayList over a LinkedList, but I've been using LinkedLists for a while and haven't had any problems with them
    An ArrayList is backed by an array (which usually has more elements than the list to allow for some expansion). A LinkedList is a series of objects where each has an associated pointer to the previous and next item in the list.

    Sequential iteration and random access to an ArrayList is quicker than a LinkedList because it's just indexing an array. A LinkedList has to work through a chain of pointers. Adding or removing elements at the end of the list is also quicker with ArrayList, although there are times when the backing array fills up and needs to be reallocated. This can be reduced by setting the initial capacity of the list with the ArrayList constructor.

    LinkedList can outperform ArrayList if there are lots of insertions and deletions other than at the end of the list because all it has to do is manipulate the "previous" and "next" pointers. Adding an element in the middle of an ArrayList results in all the elements in the "tail" being shunted to the right.

    The memory usage is also different. With a LinkedList, each element has two pointers associated with it and that creates a fixed overhead (16 bytes per element on a 64-bit machine). An ArrayList has no overhead for individual elements but there will usually be spare slots at the end of the backing array. These can be trimmed using trimToSize() when your list reaches capacity.

    So it depends on your application, but one or the other isn't suited to every case. As a general rule of thumb, I'd tend to use LinkedList if there was lots of random updating, but ArrayLists most of the time.

    For a standalone or small application where there's plenty of memory and CPU available, it doesn't make that much difference in the whole scheme of things but it's a good habit to think about it and to use List to make a switch easier.

  9. #9
    Join Date
    Mar 2010
    Location
    London
    Beans
    924

    Re: Iterators in Java

    Quote Originally Posted by orrymr View Post
    Also, KdotJ, I'm not sure why I'd want to declare my list as the most abstract type available?
    Just to add weight to what others have said, it's all about how implementation may differ. It can be confusing to understand why, I'll try give you just one reason that this is good practice. There are, of course, many other reasons.

    So let us keep with your example of using LinkedLists as the type. Lets say you have a method somewhere where the method header looks like this:

    Code:
    public void processFeatures(LinkedList<Features> featureList) {
        // do some stuff
    }
    Now, lets say somewhere else (may be a different class of whatever) that we make an ArrayList of features...

    Code:
    ArrayList<Features> features = new ArrayList<Features>();
    features.add(new Features(...)); // add a feature
    // ...add some more...
    // ... do some sorting...
    // ...do whatever to it.
    And now we want to process the list of features with our method we defined earlier... we cannot simply call:

    Code:
    processFeatures(features);
    because the method is expecting a LinkedList of Features... but we only have an ArrayList instead. Oh dear...


    However, if we have declared the method to be:
    Code:
    public void processFeatures(List<Features> featureList) {
        // do some stuff
    }
    and then in our other code we had intialised the list as:
    Code:
    List<Features> features = new ArrayList<Features>();
    then because the type is defined as a List<> instead, we can correctly pass this variable to the method and it will work. We can now pass any type of List to this method and it will work... such as ArrayList, LinkedList, Stack, Vector, RoleList etc.

    I hope that makes sense as an example!
    Last edited by KdotJ; March 22nd, 2012 at 11:56 PM.
    - "Make me a coffee..."
    - "No"
    - "sudo make me a coffee"
    - "OK"

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •