Some classes to showcase Java Iteratable<T>
and Iterator<E>
I've put everything in the same file by simplicity and declared inner classes static but I wouldn't recommend to do that in production code (separation of concerns).
import java.util.Iterator; | |
/** | |
* Implement Iterable pattern to iterate from a start time to an end time and by a given step. | |
* | |
* Hours don't wrap into days or overflow; 25:00:00 is a legit time for the BrokenTime class. | |
*/ | |
class Scratch { | |
static class BrokenTime implements Comparable<BrokenTime> { | |
private final int seconds; | |
public BrokenTime(int seconds) { | |
this.seconds = seconds; | |
} | |
public BrokenTime(int hours, int minutes, int seconds) { | |
this.seconds = 3600 * hours + 60 * minutes + seconds; | |
} | |
public int getHours() { | |
return Math.abs(seconds) / 3600; | |
} | |
public int getMinutes() { | |
return Math.abs(seconds) / 60 % 60; | |
} | |
public int getSeconds() { | |
return Math.abs(seconds) % 60; | |
} | |
public BrokenTime add(BrokenTime rightOperand) { | |
return new BrokenTime(this.seconds + rightOperand.seconds); | |
} | |
public static BrokenTimeIterable from(BrokenTime start) { | |
return new BrokenTimeIterable(start, null, new BrokenTime(3600)); | |
} | |
@Override | |
public String toString() { | |
String displaySign = seconds < 0 ? "-" : ""; | |
return String.format("%s%02d:%02d:%02d", displaySign, getHours(), getMinutes(), getSeconds()); | |
} | |
@Override | |
public int compareTo(BrokenTime o) { | |
return this.seconds - o.seconds; | |
} | |
} | |
static class BrokenTimeIterable implements Iterable<BrokenTime> { | |
private final BrokenTime start; | |
private final BrokenTime end; | |
private final BrokenTime step; | |
public BrokenTimeIterable(BrokenTime start, BrokenTime end, BrokenTime step) { | |
this.start = start; | |
this.end = end; | |
this.step = step; | |
} | |
@Override | |
public String toString() { | |
Object intervalEnd = end != null ? end : "end of time"; | |
return String.format("BrokenTimeIterable{from '%s' to '%s' by '%s'}", start, intervalEnd, step); | |
} | |
@Override | |
public Iterator<BrokenTime> iterator() { | |
return new BrokenTimeIterator(this); | |
} | |
public BrokenTimeIterable to(BrokenTime end) { | |
return new BrokenTimeIterable(this.start, end, this.step); | |
} | |
public BrokenTimeIterable by(BrokenTime step) { | |
return new BrokenTimeIterable(this.start, this.end, step); | |
} | |
} | |
static class BrokenTimeIterator implements Iterator<BrokenTime> { | |
private final BrokenTimeIterable iterable; | |
private BrokenTime next; | |
public BrokenTimeIterator(BrokenTimeIterable iterable) { | |
this.iterable = iterable; | |
this.next = iterable.start; | |
} | |
@Override | |
public String toString() { | |
return String.format("BrokenTimeIterator{from '%s' to '%s' by '%s' at '%s'}", iterable.start, iterable.end, iterable.step, next); | |
} | |
@Override | |
public boolean hasNext() { | |
return iterable.end == null || iterable.end.compareTo(next) >= 0; | |
} | |
@Override | |
public BrokenTime next() { | |
BrokenTime next = this.next; | |
this.next = this.next.add(iterable.step); | |
return next; | |
} | |
} | |
public static void main(String[] args) { | |
BrokenTime start = new BrokenTime(12, 0, 0); | |
BrokenTime end = new BrokenTime(18, 0, 0); | |
BrokenTime step = new BrokenTime(0, 30, 0); | |
System.out.println("# Bounded iterable"); | |
for (BrokenTime t : BrokenTime.from(start).to(end)) { | |
System.out.println(t); | |
} | |
System.out.println("# Unbounded iterable"); | |
Iterable<BrokenTime> myLovelyIterable = BrokenTime.from(start).by(step); | |
System.out.println(myLovelyIterable); | |
int count = 0; | |
for (BrokenTime t : myLovelyIterable) { | |
if (++count > 10) { // Because the iterable doesn't have a end, you can put whatever value you want | |
break; | |
} | |
System.out.println(t); | |
} | |
System.out.println("# Bounded iterator"); | |
Iterator<BrokenTime> myLovelyIterator = BrokenTime.from(start).to(end).iterator(); | |
while (myLovelyIterator.hasNext()) { | |
System.out.println(myLovelyIterator); | |
System.out.println(myLovelyIterator.next()); | |
} | |
} | |
} |