Creating a series using iterators
I would like to write a class (called Seii) that is basically a sequence of integers starting at s0. s0 is set in the constructor:
se + 1 = 3*(se/2)
Capture: a for loop must be able to iterate over objects of this class and spit out the elements of the sequence (without the starting number s0). Also, the sequence ends with the first element greater than 42.
For example:
for(int i:new Seii(2)){
System.out.println(i)
gives out:
3,4,6,9,10,15,16,24,36,54
I would like to do this with iterators. Can anyone help me? My idea would be to rewrite the next () method so that it does the computation for the next element of the sequence, but I don't get anywhere with the logic of that.
public class Seii<T> implements Iterator {
private ArrayList<Integer> list = new ArrayList<>();
Iterator<Integer> it = list.iterator();
private final int size;
public Seii(int size) {
this.size = size;
}
int seii = 0;
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}
@Override
public Object next() {
if ((size % 2) == 0) {
seii = 3 * (seii/2);
return seii;
}
}
}
}
This is my implementation.
source to share
Seii
must implement Iterable<Integer>
, allowing it to support extended loop syntax. The easiest way to do this, IMHO, is to simply have an inner class Iterator
that implements your logic:
public class Seii implements Iterable<Integer> {
private class SeiiIterator implements Iterator<Integer> {
@Override
public boolean hasNext() {
return value <= 42;
}
@Override
public Integer next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
value = 3 * (value / 2);
return value;
}
}
private int value;
public Seii(int value) {
this.value = value;
}
@Override
public Iterator<Integer> iterator() {
return new SeiiIterator();
}
}
source to share
You don't need to keep the sequence, so the array list can be removed from your implementation. All you need is the last value that can be set in the constructor:
// This is a wrapper class that constructs iterators.
// It is used for plugging in your code into enhanced "for" loop
class Seii implements Iterable<Integer> {
private int current;
private int max;
public Seii(int current, int max) {
this.current = current;
this.max = max;
}
@Override
public Iterator<Integer> iterator() {
return new SeiIterator(current, max);
}
}
// This is the actual iterator that maintains state
// and produces the desired sequence.
class SeiIterator implements Iterator<Integer> {
private int current;
private int max;
public SeiIterator(int current, int max) {
this.current = current;
this.max = max;
}
@Override
public boolean hasNext() {
return current < max;
}
@Override
public Integer next() {
current = (3*current)/2;
return current;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
Note that in order to use your iterator in an extended loop, for
you need to wrap it in Iterable<Integer>
.
source to share