Iterators, Functors and Predicates

In this post I am sharing different ways to create ‘Custom Iterators’ and how to control the behavior of that Iterator.

Also part of this article focuses on how to apply different operations on a selected elements within a custom iterator.

The way to do this is to implement a new Iterator-subclass and pass it Functors and Predicates.

By the way Google has implemented all these and more within the Guava Framework, you just need to include this framework as part of your project.

So what are functors and predicates?

Functor: Functor is an interface implementation that apply an operation or status change on an object passed to it’s operation method.

Functor Interface

package com.sourceallies.test.functor;
/**
 * General interface that will be implemented later to apply one operation on a
 * T object
 * 
 * @author ghaith
 * 
 * @param T
 */
public interface Functor<T> {
        public void doYourOperation(T t);
}

Functor Implementation

package com.sourceallies.test.functor;
 
import com.sourceallies.test.model.Book;
 
/**
 * Functor implementation that operates on a 'Book' 
 * object by increasing it price with amount passed in the constructor
 * 
 * @author ghaith
 * 
 */
public class PriceRiser implements Functor<Book> {
        private int increase;
 
        public PriceRiser(int increase) {
                this.increase = increase;
        }
        @Override
        public void doYourOperation(Book t) {
                t.setPrice(t.getPrice() + increase);
        }
}

Predicate: A special type of functor that applies a validate operation on an object that is passed to it’s operation method. This method returns true or false.

Predicate Interface

package com.sourceallies.test.predicate;
/**
 * general interface that used to check 
 * for a condition on the Object of class T
 * @author ghaith
 * 
 * @param T
 */
public interface Predicate<T> {
        public boolean check(T t);
}

Predicate Implementation

package com.sourceallies.test.predicate;
 
import com.sourceallies.test.model.Book;
 
/**
 * Check if book price is less than or 
 *equal a passed amount
 * @author ghaith
 *
 */
public class PriceLessThanOrEq implements Predicate<Book> {
 
        private int minPrice;
 
        public PriceLessThanOrEq(int minPrice) {
                this.minPrice = minPrice;
        }
 
        @Override
        public boolean check(Book t) {
                if (t != null) {
                        return t.getPrice() <= this.minPrice;
                }
                return false;
        }
}

This example uses a functional approach where you can pass “map and reduce” clojures to the iteration code line to select and change items of the Iterable list.

In functional languages we can do the following:

//pseudo code
fun reduce={it>20}
fun map = {print(it)}
[1,2,3,30,70].iterate(reduce,map);

and the output is:
30 70

I think this is very cool.

..................
/**
* This line of code iterates on the 'Books List' select the items that has a price more than 20
* and Print every selected item.
*/
 for (Book book : bookCat.getPriceFilterAndPrintIterable(new BookPrinter(), new PriceMoreThan(20)));
 
..................

Here’s a git repository so you can download and run the complete project.

Run the following git command to clone the project:

git clone https://galrabadi@bitbucket.org/galrabadi/iteratorlab.git