Posted on Jul 30, 2009

FilterQ – A lightweight filtering API for Iterable Objects.

Wow, version 0.3 of FilterQ has been released and is available at filterq.googlecode.com. Several cool features have been added, several bugs have been fixed. But the best of all things, at least for me, is that I am using it in my JUnit 4.5 extensions project. FilterQ is my lightweight filtering API for Iterable Objects (yeah, you got it right, it is an API for objects implementing the Java’s Iterable interface). The concepts behind FilterQ’s API have been inspired by LinQ, and Quaere use cases. In order to illustrate its specific API methods, I have compiled some interesting usage scenarios, which will be distributed in 3 posts. The first post will illustrate the basic usage scenarios. While these are small scenarios they convey the power of this API.

Basic usage scenarios
1. basic filtering


// select all the prime numbers found within (0...1000),
// while making sure that that 117 is not included in our result.
from(range(1,1000)).where(numIsPrime()).select(not(eq(117)));
// or simply
from(range(1,1000, numIsPrime().or(not(eq(117))))).select();

//  which one should I choose? well, it depends. If you prefer readability
//  over brevity, then choose the first one.

2. dealing with results


//  from the above results, count all of the prime numbers greater than 100 and less than 500.
//  Let's assume that the result is stored in a var of type "Iterable<Integer>" called foo.
count(foo, gt(100).and(lt(500));

// or simply count them all
count(foo);

3. dealing with two Iterables in a single loop


for(Integer each : intersect(range(1,100, mod(3)), range(60,250, mod(13)))){
       System.out.println(each)
}

// or
for(Integer each : union(range(1,100, mod(3)), range(60,250, mod(13))))){
	System.out.println(each)
}

3. dealing with transformations


final Integer[] numbers = {5, 4, 1, 3, 9, 8, 6, 7, 2, 0};
final String[]   strings   = {"zero","one","two","three","four","five","six","seven","eight", "nine" };
final Iterable<String>  result  =  from(numbers).apply(indexed(strings));

System.out.println(asList(result));
// result: five, four, one, three, nine, eight, six, seven, two, zero	

4. skipping elements


from(Arrays.asList(1, 2, 3, 40, 20, 30, 100)}).where(gt(20).and(lt(100))).skip(1);
// and the result is?

5. ordering elements


from(Arrays.asList("John", "Mary", "Roberto", "David", "Fernando")).orderBy(length()).select();
// and the result is? [John, Mary, David, Roberto, Fernando]

6. dealing with objects’ private members


final Person a = new Person("John", "Peterson");
final Person b = new Person("Pete", "Peterzon");

final List<Person> ppl = Arrays.asList(a, b);
final Iterable<Person> t = from(ppl).where(eq("lastName", "Peterson")).select();

System.out.println(t);
// and the result is?	   	   

7. concatenating elements


final List<Integer> a = Arrays.asList(1, 2, 3, 3, 4);
final List<Integer> b = Arrays.asList(2, 3, 4);

final Iterable<Integer> result = concat(a, b);
System.out.println(result);

// and the result is?

This is all for today. I’ve just covered the first out of 3 posts covering FilterQ’s usage scenarios. Next post will illustrate other functionality, such as FilterQ’s XML support and Java Reflection API. Till next time.

Posted on Oct 17, 2008

More on Filters as First-class functions.

By expanding (more like enhancing :) ) the filter pattern described here and borrowing some of the beauties of the matcher pattern in Guice, I coded a more concise version of this filter pattern. Now this pattern’s implementation has a fluent API for combining other filters together, a place where all filters can be defined, a way of negating filters, etc. Further in this post I will provide a simple example that describes how the newer version of this pattern can be utilize. But before showing the example, I will provide the pattern’s newer definition and implementation herein.

Filter pattern’s main interface…


public interface Filter <T> {
    Filter <T> and(Filter <? super T> thing);
    Iterable <T> filter(Iterable <T> thing);
    boolean evaluate(T thing);
    Filter <T> or(Filter <? super T> thing);
}

and its abstract implementation…


public abstract class AbstractFilter <T> implements Filter <T> {
    public Filter<T> and(Filter<? super T> thing) {
        return new AndFilter<T>(this, thing);
    }

    public Iterable<T> filter(final Iterable<T> thing) {
        return new Iterable<T>(){
            public Iterator<T> iterator() {
                return new FilteringIterator<T>(
                	AbstractFilter.this,
                	thing.iterator()
                );
            }
        };
    }

    public Filter<T> or(Filter<? super T> thing) {
        return new OrFilter<T>(this, thing);
    }

    private static class AndFilter<T> extends AbstractFilter<T> {
        private final Filter<? super T> one;
        private final Filter<? super T> two;

        AndFilter(
        	Filter<? super T> one,
            Filter<? super T> two
        ) {
            this.one = one;
            this.two = two;
        }

        public boolean evaluate(T thing) {
            return one.evaluate(thing)
            	   && two.evaluate(thing);
        }
    }

    private static class OrFilter<T> extends AbstractFilter<T> {
        private final Filter<? super T> one;
        private final Filter<? super T> two;

        OrFilter(
        	Filter<? super T> one,
            Filter<? super T> two
        ) {
            this.one = one;
            this.two = two;
        }

        public boolean evaluate(T thing) {
            return one.evaluate(thing)
            	   || two.evaluate(thing);
        }
    }

    private static class FilteringIterator<T> implements Iterator <T> {
        private final Filter <T>     filter;
        private final Iterator <T>   base;
        private       T              next;

        FilteringIterator(
        	Filter<T> filter,
        	Iterator<T> base
        ){
            this.filter = filter;
            this.base = base;
            tryNext();
        }

        private void tryNext() {
            next = null;
            while (base.hasNext()) {
                final T item = base.next();
                if (item != null && filter.evaluate(item)) {
                    next = item;
                    break;
                }
            }
        }

        public boolean hasNext() {
            return next != null;
        }

        public T next() {
            if (next == null) throw new NoSuchElementException();
            final T returnValue = next;
            tryNext();
            return returnValue;
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
}

Now that I have provided this pattern’s definition and implementation, I will proceed with a simple example of its use. This example will deal with the Java Reflection API. Imagine that you are trying to query all the methods in a class which names start with “eq”, “has”, “toS” and have the Object class as a parameter. Most of the times you will have multiple IFs checking the methods of your interest. What if I don’t want to do that and instead, I want to use the Filter design pattern. Well, in order to do that all you need to code are two basic filters: one for looking at the methods’ names and the other one for looking at the methods’ parameters types.


    public static Filter <Method> containedParameters(final Class<?>... params){
        return new AbstractFilter <Method>(){
            public boolean evaluate(Method thing) {
                final List<Class<?>> s = Arrays.asList(
                	thing.getParameterTypes()
                );

                for(Class<?> each : params){
                    if(s.contains(each)){
                        return true;
                    }
                }
                return false;
            }
        };
    }

    public static Filter <Method> startedWith(final String... prefixes) {
        return new AbstractFilter <Method>(){
            public boolean evaluate(Method thing) {
                for(String prefix : prefixes) {
                    if(thing.getName().startsWith(prefix)){
                        return true;
                    }
                }
                return false;
            }
        };
    }

Simple, huh? totally!
Well, what if you want to negate one of those filters? Well, this is even simpler to implement:


    public static <T> Filter <T> not(final Filter <T> filter) {
        return new AbstractFilter <T>(){
            public boolean evaluate(T thing) {
                return !filter.evaluate(thing);
            }
        };
    }

And to finalize this post, here is how to put these filters to work:


public class RunPattern {
    private RunPattern(){}
    public static void main(String... args) {
        // calling filters one after another
        for(Method each : containedParameters(Object.class)
        	.filter(startedWith("eq", "has", "toS")
        	.filter(Arrays.asList(Object.class.getDeclaredMethods())))){
           System.out.println(each.getName());
        }

        // or maybe you can start using and & or operators
        final Filter <Method> m1 = containedParameters(Object.class)
        						   .and(startedWith("eq", "has", "toS"));

        for(Method each : m1.filter(Arrays.asList(Object.class.getDeclaredMethods()))){
            System.out.println(each.getName());
        }

        // which method do you you prefer?
        // it will be up to you...

        // hmmm....what if?
        final Filter <Method> m2 = not(containedParameters(Object.class))
        						   .and(startedWith("eq", "has", "toS"));
        for(Method each : m2.filter(Arrays.asList(Object.class.getDeclaredMethods()))){
            System.out.println(each.getName());
        }

    }
}

Hopefully you will find this newer version of this pattern useful. Ciao!