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.

+3


source to share


3 answers


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();
    }
}

      

+3


source


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>

.

Demo version

+3


source


Your class Seii

must implement Iterable<Integer>

not Iterator

, as it requires the interface required by the for loop. It will have a method Iterator

that returns an instance of the class that implements the interface Iterator<Integer>

.

0


source







All Articles