DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Handy Iterable For A Range Of Integers

04.10.2007
| 6113 views |
  • submit to reddit
        Looping a specific number of times produces code a bit too verbose in Java.  The JDK5 enhanced for statement is a handy improvement, but you still have to fall back to the traditional for statement if you want to repeat a loop, say, 10 times.

Not with this implementation of Iterable.  You can use it like this:

for (int i : new Range(100))
    System.out.printf("I have said this %d times. Read dzone.com!%n", i);

class Range implements Iterable<Integer> {
    
    private final Integer stop;
    
    public Range(int stop) {
        this.stop = stop;
    }

    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            
            private Integer counter = 0;

            public boolean hasNext() {
                return (counter != stop);
            }

            public Integer next() {
                if (counter == stop)
                    throw new NoSuchElementException();
                return ++counter;
            }

            public void remove() {
            }};
    }
    
}
    

Comments

Snippets Manager replied on Fri, 2007/04/20 - 3:31am

Sometime ago I realized the same problem. I posted the source code here; http://www.tutego.com/blog/javainsel/2007/04/range-in-java.html and for short: package com.tutego; import static com.tutego.Range.range; public class RangeDemo { public static void main( String[] args ) { for ( int i : range( 10 ) ) System.out.print( i + " " ); System.out.println(); for ( int i : range( 5, 10 ) ) System.out.print( i + " " ); System.out.println(); for ( int i : range( 0, 10, 3 ) ) System.out.print( i + " " ); System.out.println(); for ( int i : range( '0', '9' ) ) System.out.print( (char) i ); System.out.println(); String[] a = { "Mary", "had", "a", "little", "lamb" }; for ( int i : range(a.length ) ) System.out.printf( "%d %s%n", i, a[i] ); } } And the main class Range /* * This project is made available under the terms of the BSD license, more information can be found at * http://www.opensource.org/licenses/bsd-license.html * * Copyright (c) 2007. Christian Ullenboom (http://www.tutego.com/) and contributors. All rights reserved. */ package com.tutego; import java.util.Iterator; /** * Class that generates immutable sequences (ranges) as Iterable * objects. A range represents a start (0 if not given), an stop (mandatory) and * an optional step (1 by default). The start value is included in the range, * the stop value is exclusive. Every range is handled by an Iterable * which can by used in an extended for loop. * *
 * for ( int i : range( 0, 10, 3 ) )
 *   System.out.print( i + " " ); // 0 3 6 9
 * 
* * @author Christian Ullenboom (tutego) * @version 1.0 */ public class Range { public static Iterable range( final int start, final int stop, final int step ) { if ( step <= 0 ) throw new IllegalArgumentException( "step > 0 isrequired!" ); return new Iterable() { public Iterator iterator() { return new Iterator() { private int counter = start; public boolean hasNext() { return counter < stop; } public Integer next() { try { return counter; } finally { counter += step; } } public void remove() { } }; } }; } public static Iterable range( final int start, final int stop ) { return range( start, stop, 1 ); } public static Iterable range( final int stop ) { return range( 0, stop, 1 ); } }

Alan Moore replied on Sat, 2007/04/14 - 6:53pm

Nice tip, but there's a problem. Use an upper bound of 128 instead of 100, and you'll get an infinite loop. That's because you're doing an identity comparison on auto-boxed Integer objects using == and !=. You get away with it for values from -128 to 127 because they're cached, but they are objects, so you should be using equals(). However, a better solution would be to declare the "stop" and "count" fields as ints, not Integers; that will make it easier to add support for negative bounds and "step" increments greater than one.