Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mtorchiano/09d8af24702aff217d8c to your computer and use it in GitHub Desktop.
Save mtorchiano/09d8af24702aff217d8c to your computer and use it in GitHub Desktop.
Incremental Transformation of an Iterable Sequence in Java

Incremental Transformation of an Iterable Sequence in Java

Creative Commons License
This work by Marco Torchiano is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.


This is an example of the iterative and incremental use of patterns and language idioms to improve an initial simple solution. This example was originally developed for the Object Oriented Programming course at Politecnico di Torino

Simple sequence

The class RandomSequence provides as basic feature the generation of a sequence of random integer numbers that can be iterated upon. The method next() returns the next number in the sequence.

In addition the sequence can be regenerated using renew() and the iteration can start again from the first element with restart().

Code: RandomSequence.java

Limitations:

  • one iteration at a time can be perfomed
  • custom code must be written (e.g. no for-each construct can be used)

Iterable sequence

Using the iterator pattern support in Java, an iterable version is generated.

The main class implements the Iterable interface (an abstract factory of iterators). The factory method (iterator()) returns a new RIterator, which implements the Iterator interface.

RIterator is a nested class that contains an index (initialized to 0) and a reference to the array cotaining the sequence (initialized using the reference to the sequence object).

Code: IterRandomSequence.java

Limitations:

  • there are two reference to the sequence array, one in the main sequence class and one in the iterator class,
  • the initialization of the iterator needs a (avoidable) this argument.

Inner Iterable sequence

Using the features of inner classes, i.e. the automatic linkage to the creator enclosing class instance, the code of the iterator class can be simplified

Code: InnerIterRandomSequence.java

Limitations:

  • iterator class RIterator is used only once, though it has a name

Anonymous Inner Iterable sequence

The usage of an anonymous inner class allow defining the iterator class and instantiating it without the need to provide a name.

The resulting code is even more compact.

Code: AnonInnerIterRandomSequence.java

Limitations

  • the return type of the next() method is an Object, thus an explicit cast is required

Anonymous Generic Inner Iterable sequence

The generic interfaces Iterable and Iterator can be parameterized with the actual (wrapper) type of the elements of the sequence.

Code: AnonGenericInnerIterRandomSequence.java

import java.util.Iterator;
public class AnonGenericInnerIterRandomSequence implements Iterable<Integer> {
private final int start;
private final int stop;
private final int[] sequence;
public AnonGenericInnerIterRandomSequence(int n, int start, int stop){
this.start=start;
this.stop=stop;
sequence = new int[n];
renew();
}
public void renew(){
for(int i=0; i<sequence.length; ++i){
sequence[i] = (int)Math.round(start+Math.random()*(stop-start)-0.5);
}
}
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>(){
private int position=0;
public boolean hasNext() {
return position<sequence.length;
}
public Integer next() {
return sequence[position++];
}
};
}
}
import java.util.Iterator;
public class AnonInnerIterRandomSequence implements Iterable {
private final int start;
private final int stop;
private final int[] sequence;
public AnonInnerIterRandomSequence(int n, int start, int stop){
this.start=start;
this.stop=stop;
sequence = new int[n];
renew();
}
public void renew(){
for(int i=0; i<sequence.length; ++i){
sequence[i] = (int)Math.round(start+Math.random()*(stop-start)-0.5);
}
}
// private class RIterator implements Iterator {
// private int position;
//
// @Override
// public boolean hasNext() {
// return position<sequence.length;
// }
//
// @Override
// public Object next() {
// return sequence[position++];
// }
//
// }
@Override
public Iterator iterator() {
return new Iterator(){
private int position=0;
public boolean hasNext() {
return position<sequence.length;
}
public Object next() {
return sequence[position++];
}
};
}
}
import java.util.Iterator;
public class InnerIterRandomSequence implements Iterable {
private final int start;
private final int stop;
private final int[] sequence;
public InnerIterRandomSequence(int n, int start, int stop){
this.start=start;
this.stop=stop;
sequence = new int[n];
renew();
}
public void renew(){
for(int i=0; i<sequence.length; ++i){
sequence[i] = (int)Math.round(start+Math.random()*(stop-start)-0.5);
}
}
private /*static*/ class RIterator implements Iterator {
private int position;
// private int[] sequence;
// RIterator(IterRandomSequence parent){
// this.sequence=parent.sequence;
// }
@Override
public boolean hasNext() {
return position<sequence.length;
}
@Override
public Object next() {
return sequence[position++];
}
}
@Override
public Iterator iterator() {
return new RIterator(/*this*/);
}
}
import java.util.Iterator;
public class IterRandomSequence implements Iterable {
private final int start;
private final int stop;
private final int[] sequence;
// private int current=0;
public IterRandomSequence(int n, int start, int stop){
this.start=start;
this.stop=stop;
sequence = new int[n];
renew();
}
public void renew(){
for(int i=0; i<sequence.length; ++i){
sequence[i] = (int)Math.round(start+Math.random()*(stop-start)-0.5);
}
// restart();
}
// public void restart(){
// current=0;
// }
private static class RIterator implements Iterator {
private int position;
private int[] sequence;
RIterator(IterRandomSequence parent){
this.sequence=parent.sequence;
}
@Override
public boolean hasNext() {
return position<sequence.length;
}
@Override
public Object next() {
return sequence[position++];
}
}
// public int next(){
// return sequence[current++];
// }
//
@Override
public Iterator iterator() {
return new RIterator(this);
}
}
public class RandomSequence {
private final int start;
private final int stop;
private final int[] sequence;
private int current=0;
public RandomSequence(int n, int start, int stop){
this.start=start;
this.stop=stop;
sequence = new int[n];
renew();
}
public void renew(){
for(int i=0; i<sequence.length; ++i){
sequence[i] = (int)Math.round(start+Math.random()*(stop-start)-0.5);
}
restart();
}
public void restart(){
current=0;
}
public int next(){
return sequence[current++];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment