Iterating on non-iterable classes

Posted by Lucio Benfante Fri, 27 Jul 2007 04:42:00 GMT

(You’ll find all the code of this post in Benfante’s Utilities mini-library)

One of the futures I ‘m reappraising is the JDK 5 enhanced for statement.

I still consider it too limited, but it’s very comfortable in the simplest (and maybe common) cases.

But…what if the elements on which you want to iterate are not managed by an Iterable class?

For example, this happens with the XOM library, where the Element.getChildElements returns an instance of the Elements class, wich is neither a Collection, or an Iterable class. So, for iterating on children elements, you have to use the basic for statement:

for (int i=0; i < elements.size(); i++) {
  Element element = elements.get(i);
  // etc...
}

I would like to write simply:

for (Element element: elements) {
  // etc...
}

So I wrote an Iterabletor class that builds a proxy around a class, enhancing it with the Iterable interface.

Now You can write:

Iterable<Element> iterable =
  new Iterabletor<Element>(elements).getIterable();

for (Element element: iterable) {
  // etc...
}

Take a look at how I realaized this.

First, the Iterabletor class:

package com.benfante.utils.iterabletor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Iterator;

/**
 * A class for add iterability to another class
 * 
 * @author lucio
 */
public class Iterabletor<T> implements InvocationHandler {

    private final Object obj;
    private Class<? extends Iterator> iteratorClass;

    /**
     * Prepare for iterability the passed object using a XOMIterator.
     *
     * @param The object on which iterate.
     */
    @SuppressWarnings(value = "unchecked")
    public Iterabletor(Object obj) {
        this.obj = obj;
        this.iteratorClass = XOMIterator.class;
    }

    /**
     * Prepare for iterability the passed object using the passed iterator class.
     *
     * @param The object on which iterate.
     */
    public Iterabletor(Object obj, Class<? extends Iterator> iteratorClass) {
        this.obj = obj;
        this.iteratorClass = iteratorClass;
    }

    @SuppressWarnings(value = "unchecked")
    public synchronized Iterable<T> getIterable() {
        Class<?> objClass = obj.getClass();
        Class<?>[] oldInterfaces = objClass.getInterfaces();
        Class<?>[] newInterfaces = new Class<?>[oldInterfaces.length + 1];
        System.arraycopy(oldInterfaces, 0, newInterfaces, 0, oldInterfaces.length);
        newInterfaces[newInterfaces.length - 1] = Iterable.class;
        return (Iterable<T>) Proxy.newProxyInstance(objClass.getClassLoader(),
                newInterfaces,
                this);
    }

    @SuppressWarnings(value = "unchecked")
    private Iterator<T> iterator() {
        try {
            return (Iterator<T>) iteratorClass
                .getConstructor(Object.class).newInstance(obj);
        } catch (Exception e) {
            throw new UnsupportedOperationException("No contructor(object)", e);
        }
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.getName().equals("iterator")) {
            return this.iterator();
        } else {
            try {
                return method.invoke(obj, args);
            } catch (InvocationTargetException ite) {
                throw ite.getCause();
            }
        }
    }
}

The default Iterator is XOMIterator (you can imagine why this name :) ), which reflect on the “collection”, calling the get(int) and size() methods:

package com.benfante.utils.iterabletor;

import java.util.Iterator;
import org.apache.log4j.Logger;

/**
 * An Iterator for XOM-like collection classes
 * ...i.e. classes with get(int) and size() methods.
 * 
 * @author lucio
 */
public class XOMIterator<T> implements Iterator<T> {

    private static final Logger logger = Logger.getLogger(XOMIterator.class);
    private Object obj;
    private int index;

    public XOMIterator(Object obj) {
        this.obj = obj;
    }

    public boolean hasNext() {
        try {
            int count = ((java.lang.Integer) obj.getClass()
                    .getMethod("size", new Class[0])
                    .invoke(obj)).intValue();
            return index < count;
        } catch (Exception ex) {
            logger.error("No size() method in the target object ("
                    + obj.getClass().getName() + ")", ex);
            throw
                    new UnsupportedOperationException(
                    "No size() method in the target object ("
                    + obj.getClass().getName() + ")", ex);
        }
    }

    @SuppressWarnings(value = "unchecked")
    public T next() {
        try {
            return (T) obj.getClass()
                    .getMethod("get", new Class<?>[]{int.class})
                    .invoke(obj, new Integer(index++));
        } catch (Exception ex) {
            logger.error("No get(int) method in the target object ("
                    + obj.getClass().getName() + ")", ex);
            throw
                    new UnsupportedOperationException(
                    "No get(int) method in the target object ("
                    + obj.getClass().getName() + ")", ex);
        }
    }

    public void remove() {
        throw new UnsupportedOperationException("Not supported.");
    }
}

Of course, You can use a different Iterator:

Iterator<MyElement> iterable =
    new Iterabletor<MyElement>(element, MyIterator.class)
        .getIterable();

Posted in ,  | Tags , , , ,  | 38 comments

Comments

  1. Avatar enrico.giurin@jugpadova.it said about 9 hours later:

    It seems interesting. It would be convenient to define a lot of Iterator class for all the commons collection-like-class, i.e. Elements of Xom.

  2. Avatar NFL Jerseys said 1375 days later:

    Your website is so great that i love it very much. welcome to visit our http://www.nfls.cc to get more great products.

  3. Avatar New Jordans said 1395 days later:

    That may be great that should be shady on the comprehensive practise due to a small number of damaging oatmeal? There is more than couple of valuable variance, they may be opinion. First of all, normally fears which usually knowledge actually works, no matter wrong and additionally fraudulent case will probably now and again come to be obtainable. Still when there is whatever “miraculous” permanent cures right from faith-healing, over the human body’s personally own power to fix its own matters, could be very a whole lot located at subject. Also, all the expose’ about rip-off and additionally corruption for knowledge created from basically purely just by knowledge. However, the key advertising mileage about rip-off and additionally corruption for faith-healing is almost do not conducted just by other sorts of faith-healers.

  4. Avatar Nike Air Jordan Shoes 2011 said 1399 days later:

    For ages, a good unsafe contradiction has long been waged somewhere between a handful of brave the sexes for notion together with prodigy in the main edge, and also terrific uninformed devout mass fast over the many other. Right here is the world war somewhere between Development together with Beliefs. Any couple own appealed that will factor, that will honour, that will laws, that will convenience, into the recognised, as well as joy and happiness at this point in this world. Many own appealed that will prejudice, that will panic, that will sensation, that will slavery, into the anonymous, as well as strain hereafter. Any couple own says “Think” Many own says “Believe! “

  5. Avatar find a freelancer said 1402 days later:

    very happy to found this blog and I’ll must bookmark it.

  6. Avatar dermal fillers melbourne said 1402 days later:

    That is nice to definitely find a site where the blogger knows what they are talking about!

  7. Avatar jack sparrow said 1403 days later:

    There are many problem using XOM library. Your post is good. thanks for information.

    natural anxiety cure

  8. Avatar New Jordans 2011 said 1414 days later:

    daddies have been skeptics or perhaps Deists; they will especially designed any high-end authorities having an “unbreachable wall” among cathedral and also express; they will also published in to the treaty with all the Moslem region regarding Tripoli an obvious assertion in which, as opposed to Countries in europe, the particular “United Declares just isn’t, in different perception, any Orlando region. inches (So plainly comprehended has been the particular basic principle regarding divorce regarding cathedral and also express then though the treaty approved The legislature without the argument about in which term, and also Chief executive David Adams agreed upon that simultaneously, without the dread which it may well risk his / her political upcoming. )

  9. Avatar New Jordans said 1425 days later:

    Don’t believe anything at all. Consider items over a level regarding possibilities. What seem to be many ludicrous, set beneath ‘Low Probability’, and also what seem to be many credible, an individual set beneath ‘High Probability’. By no means feel anything at all. As soon as you feel anything at all, an individual quit great deal of thought. The harder items you imagine, the particular a smaller amount emotional action. In the event you feel one thing, and possess an impression about each subject matter, in that case your human brain action prevents totally, which can be medically regarded an indication regarding dying, today inside health-related training. Thus set items over a level or perhaps possibility, rather than feel or perhaps disbelieve anything at all totally.

  10. Avatar Cheap Vibram Five Fingers said 1433 days later:

    In addition does it have plenty of plugins and themes for it? I might wish to start off applying it for my new blog if it does.

  11. Avatar New Jordans 2011 said 1434 days later:

    Don’t believe anything. Regard things on a scale of probabilities. The things that seem most absurd, put under ‘Low Probability’, and the things that seem most plausible, you put under ‘High Probability’. Never believe anything. Once you believe anything, you stop thinking about it. The more things you believe, the less mental activity. If you believe something, and have an opinion on every subject, then your brain activity stops entirely, which is clinically considered a sign of death, nowadays in medical practice. So put things on a scale or probability, and never believe or disbelieve anything entirely.

  12. Avatar snoring mouthpiece reviews said 1452 days later:

    I absolutely liked the way you have designed your blog, it’s simple, neat, simple to navigate and incredibly easy on the eyes. Can you tell me which theme or designer did you use.

  13. Avatar Cheap Air Max said 1452 days later:

    Any Holy book has long been construed that will excuse these types of malefic strategies mainly because, including, slavery, any slaughter for prisoners for world war, any sadistic murders for most women believed to be witches, budget consequences meant for 100s of offenses, polygamy, together with cruelty that will critters. This has been useful to persuade confidence during the grossest superstition as well as dissuade any zero cost assisting for clinical truths. We will need to never forget the fact that together superior together with malefic circulate within the Holy book. Therefore, it is possibly not higher than critique.

  14. Avatar how to quit snoring said 1458 days later:

    I am very excited that I have found your post because I have been searching for some information about it for almost three hours. You have helped me a lot and reading this your article I have found much new and useful information about this subject.

  15. Avatar Nike Air Jordan Shoes 2011 said 1458 days later:

    You certainly will achieve all of us that the law to reconsider which contain normally held the perfect of every individual to help you his particular feeling, then again distinctive which will feeling may just be to help you excavation. She or he just who denies to a new one it best causes an important servant in by his own to provide feeling considering she or he precludes by his own the perfect in replacing the application. Quite possibly the most strong item with flaws of every manner is without a doubt good reason. May possibly hardly ever implemented all other, and even As i faith As i hardly ever would certainly.

  16. Avatar Nursing home Swadlincote said 1510 days later:

    Looking for a nursing home in derby, with high quality nursing care with restbite nursing care assisted living. High quality purpose built nursing home is located in Swadlincote, Derbyshire nr Derby, the ideal nursing home. Nursing home Swadlincote

  17. Avatar Freelance Web Designers & Freelance Programmers said 1514 days later:

    BestFreelanceJob.com is the contract work marketplace where clients post contract jobs and freelance programmers, graphic designers, translators, consultants and other professionals bid for those jobs.

    For more details visit at: http://www.bestfreelancejob.com/

  18. Avatar Digital Signage said 1514 days later:

    Timeliness of messages and availability of your intended audience may be the most fundamental reasons digital signage is effective. Two of the most basic reasons digital signage makes sense as a communications medium are its timeliness and availability.For more details visit @ http://www.keywesttechnology.com/products/digital-signage.html

  19. Avatar recycle phones said 1517 days later:

    Mobile phone recycling UK. We recycle mobile phones. Sell mobile phones for cash, regardless of condition. Whether they are old, working, non-working or broken, sell your mobile phone for cash now.

  20. Avatar web design toronto said 1524 days later:

    Nice blog posting. Thanks for it.

  21. Avatar Kevin kentt said 1527 days later:

    Hey Nice Blog.Thank you for the valuable review.Will surely follow it. real estate investment newsletter

  22. Avatar Gold Investment said 1529 days later:

    Hey Nice blog I like your blog very much I accept with your point keep posting.

  23. Avatar Cyprus car hire said 1534 days later:

    Very good blog posting. Thanks for it.

  24. Avatar mobile phone deals said 1547 days later:

    Nice information, i found this website very useful for UK based mobile shopping, this website helped me to compare Mobile Phone Deals. Thanks again and good luck! mobile phone deals

  25. Avatar crystal bag said 1580 days later:

    Swarovski purses are well known by their special crystals and their high quality. Of course we cannot ignore the unique style of the swarovski clutch bags .We have already known that swarovski evening bags are well known not only in USA, but also even in the world. Since years of its beginning in fashion world, swarovski fashion purses have make great efforts in introducing the new era. They believe that creating new crystal clutches which could attract people’s attention and best sold in a short time based on the ideas that the public gives us endless inspiration. So imagination in designing these gemstone purses as well as crystal bridal bags plays a rather important role when it comes to swarovski bags designers. And also inspiration is not easy to get. Designer crystal bags would only achieve by experiencing new thing. http://www.crystalpurseshop.com/

  26. Avatar brown.jack76@gmail.com said 1585 days later:

    Blingsoul purses are well known by their special crystals and their high quality. Of course we cannot ignore the unique style of the bling soul clutch bags .We have already known that bling soul evening bags are well known not only in USA, but also even in the world. Since years of its beginning in fashion world, bling soul fashion purses have make great efforts in introducing the new era. They believe that creating new crystal clutches which could attract people’s attention and best sold in a short time based on the ideas that the public gives us endless inspiration. So imagination in designing these gemstone purses as well as crystal bridal bags plays a rather important role when it comes to bling soul purses designers. And also inspiration is not easy to get. Designer crystal bags would only achieve by experiencing new thing.

    http://www.blingsoul.com/

  27. Avatar brown.jack76@gmail.com said 1608 days later:

    Nice job. It’ll be useful for work.

    “rhinestone purses”

  28. Avatar Buy domain India said 1608 days later:

    This is my first time i visit here. I found so many interesting stuff in your blog especially its discussion. From the tons of comments on your articles, I guess I am not the only one having all the enjoyment here! keep up the good work.

  29. Avatar richard.smith12377@gmail.com said 1620 days later:

    Cool post, Very well done. I really like it

    “multicolor clutch bag”

  30. Avatar richard.smith12377@gmail.com said 1629 days later:

    Good one, thats a good blog. I must say that’s a creative work, I like it!!)

    “Movie Leather Jackets”

  31. Avatar Weight loss pills said 1648 days later:

    Good and helpful coding, it’s really very beneficial for java developers. www.myadipex.com

  32. Avatar http://www.solvonix.com said 1712 days later:

    Thanks for the information this blogs

  33. Avatar india to usa flights said 1741 days later:

    Thnks for sharing this Post.Such an informative Post.

    website:-http://www.usaflights.co.in

  34. Avatar Benchley Pierre said 1759 days later:

    Thanks for this post. It Very nice Blog. It was a very good Blog. I like it. Thanks for sharing knowledge. Ask you to share good Blog again.

    natural stamina enhancement

  35. Avatar GARRETT29MICHAEL said 2124 days later:

    Check this link for detailed information about how to buy an essay and we guarantee that you you will receive the highest outcomes when you check out our professional online essay writing.

  36. Avatar Rolex Replica said 2281 days later:

    Your web page is very chatty. It will be useful for all of us. You have done a perform. I will come here again to evaluate new up-dates. Thanks for publishing.

  37. Avatar tostopsnoringpr said 2407 days later:

    GOOD ONE

  38. Avatar sink said 2588 days later:

    Thanks for share this code, i hope its useful. motorku

(leave url/email »)

   Comment Markup Help Preview comment