001package functions.two;
002interface Stream {
003        int next();
004}
005
006class IntStream implements Stream {
007        private int i = -1;
008        public int next() {
009                return ++i;
010        }
011}
012
013interface Predicate{
014        boolean evaluate(int j);
015}
016
017class FilteredStream implements Stream{
018        private Stream it;
019        private Predicate p;
020
021        public FilteredStream(Stream it, Predicate p) {
022                this.it = it;
023                this.p =p;
024        }
025
026        public int next() {
027                int i;
028                do {
029                        i = it.next();
030                } while (!p.evaluate(i));
031                return i;
032        }
033}
034
035class IsEven implements Predicate {
036        public boolean evaluate(int j){
037                return (j%2)== 0;
038        }
039}
040class Main {
041        public static void main (String[] args) {
042                IntStream I = new IntStream();
043                FilteredStream F = new FilteredStream(I, new IsEven());
044                System.out.println(F.next());   // prints 0 on the screen
045                System.out.println(F.next());   // prints 2 on the screen
046                System.out.println(F.next());   // prints 4 on the screen
047                System.out.println(F.next());   // prints 6 on the screen
048                System.out.println(F.next());   // prints 8 on the screen
049
050                IntStream J = new IntStream();
051                J.next();                       // move forward one item in J
052                FilteredStream G = new FilteredStream(J, new IsEven());
053                System.out.println(G.next());   // prints 2 on the screen
054                System.out.println(G.next());   // prints 4 on the screen
055                System.out.println(G.next());   // prints 6 on the screen
056                System.out.println(G.next());   // prints 8 on the screen
057
058                IntStream K = new IntStream();
059                class Div3 implements Predicate {
060                        public boolean evaluate(int n) { return (n%3) == 0; }
061                }
062                FilteredStream H = new FilteredStream(K, new Div3());
063                System.out.println(H.next());   // prints 0 on the screen
064                System.out.println(H.next());   // prints 3 on the screen
065                System.out.println(H.next());   // prints 6 on the screen
066                System.out.println(H.next());   // prints 9 on the screen
067        }
068}