Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a Series using Iterators

Tags:

java

iterator

I would like to write a class(called Seii) that is basically a sequence of whole numbers starting from s0. s0 is set in the constructor:

se + 1 = 3*(se/2)

The catch is: A for-loop should be able to iterate through the 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 larger 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 it using iterators. Can someone pls help me out? My idea would be to rewrite the next() method so that it does the calculation for the next element of the sequence, but i'm not getting anywhere with the logic of this.

 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.

like image 498
Antoine089 Avatar asked Sep 12 '26 02:09

Antoine089


2 Answers

Seii should implement Iterable<Integer>, which will allow it to support the enhanced for loop syntax. The easiest way of doing that, IMHO, is just to have an inner Iterator class which 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();
    }
}
like image 54
Mureinik Avatar answered Sep 13 '26 14:09

Mureinik


You do not need to store the sequence, so the array list can be removed from your implementation. All you need is the last value, which 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 enhanced for loop you need to wrap it in an Iterable<Integer>.

Demo.

like image 23
Sergey Kalinichenko Avatar answered Sep 13 '26 16:09

Sergey Kalinichenko