Skip to content

Instantly share code, notes, and snippets.

@AdrienHorgnies
Last active April 14, 2020 08:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AdrienHorgnies/4b7563635b3c8e0305097e973e8a8e2d to your computer and use it in GitHub Desktop.
Save AdrienHorgnies/4b7563635b3c8e0305097e973e8a8e2d to your computer and use it in GitHub Desktop.
Playing with Iterable and Iterator

Java Iteration Design Pattern

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());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment