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.