Skip to content
Advertisement

Problem with exercise where i have to iterable through MyObject

I have exercise: define an Incrementer class to get the code from main class gave the result:

package incr;
import static incr.Incrementer.*;

    public class Test {
  
  public static void main(String[] args) {
    
    // simplest iteration - step = 1
    for(int k : in(1, 10)) System.out.print(k + " ");
    System.out.println();
    
    // The given step
    for(int k : in(1, 10).by(2)) System.out.print(k + " ");
    System.out.println();
    
    // It can be the other way around - step = -1 by default
    for(int k : in(10, 1)) System.out.print(k + " ");
    System.out.println();

    // But the range can be made from min to max and the given step will be
    // decide on the iteration direction
    for(int k : in(1, 10).by(-1)) System.out.print(k + " ");
    System.out.println();
    
    // During the iteration, you can change the step
    Incrementer inc;
    for (int i : inc = in(1,10) ) {
      if (i == 4) inc.by(2);
      System.out.print(i + " ");
    }
    System.out.println();
    for (int i : inc = in(1,10) ) {
      if (i == 8) inc.by(-2);
      System.out.print(i + " ");
    }
    System.out.println();
    for(int k : inc = in(10, 1)) {
      if (k == 5) inc.by(1);
      System.out.print(k + " ");
    }

  }

}

gave the result:

1 2 3 4 5 6 7 8 9 10 
1 3 5 7 9 
10 9 8 7 6 5 4 3 2 1 
10 9 8 7 6 5 4 3 2 1 
1 2 3 4 6 8 10 
1 2 3 4 5 6 7 8 6 4 2 
10 9 8 7 6 5 6 7 8 9 10

Requirement: the program (including the Incrementer class) cannot use tables or collections.

Hints:

in (…) and by (…) are methods in the Incrementer class Incrementer should implement the Iterable interface

MY QUESTION IS: How to iteratre throught method when in main Test class is no define Incrementer?! –> for(int k : in(1, 10)) System.out.print(k + " ");

Advertisement

Answer

I think you should be able to achieve this using a customized Iterable<Integer> class like shown below. Basically I’ve added these things in Incrementer:

  1. Incrementer has a static method in() which will receive two integers for range start and end and returns and instance of Iterator.
  2. In iterator() method, we will be returning an Interator<Integer> which would simply add step value to current value and return.
  3. hasNext() would make sure that next incoming value stays within range bounds.
  4. Incrementer would also have a by() method which would allow modification of it’s member variable step. Values of start and end would change depending on step is positive or negative
import java.util.Iterator;
import java.util.NoSuchElementException;

public class Incrementer implements Iterable<Integer> {
    private Integer current;
    private Integer step;
    private Integer start;
    private Integer end;

    public Incrementer(Integer start, Integer end) {
        this.start = start;
        this.end = end;
        this.step = start > end ? -1 : 1;
        this.current = null;
    }

    public Incrementer by(Integer offset) {
        this.step = offset;
        if ((offset < 0 && this.start < this.end) ||
                (offset > 0 && this.start > this.end)) {
            swapStartAndEnd();
        }
        return this;
    }

    private void swapStartAndEnd() {
        Integer temp = this.start;
        this.start = this.end;
        this.end = temp;
    }

    public static Incrementer in(Integer start, Integer end) {
        return new Incrementer(start, end);
    }

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            @Override
            public boolean hasNext() {
                if (current == null) {
                    return true;
                }
                return isNextValueWithinBounds(getNextValue(current));
            }

            @Override
            public Integer next() {
                if (!hasNext()) throw new NoSuchElementException();
                if (current == null) {
                    current = start;
                } else {
                    current = getNextValue(current);
                }

                return current;
            }

            private boolean isNextValueWithinBounds(Integer value) {
                if (start > end) {
                    return value >= end;
                } else {
                    return value <= end;
                }
            }

            private Integer getNextValue(Integer value) {
                return value + step;
            }
        };
    }
}

I tested it using the code you provided and was able to see desired output.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement