Play@Work

Wednesday, March 02, 2005

checkin out Jakarta Commons - Collections

Functors
- one that performs an operation or a function
- an object that encapsulates some functional logic
eg - Comparator and Iterator

why ?
code reuse
cleaner design --> abstraction

Functor interfaces available in commons:
Predicate - evaluate criteria or conditions and returns a boolean
Transformer - create a new object depending upon the input object
Factory - Create objects
Closure - act on input objects.


Using Predicates
FilterIterator

Non destructive filtering. Basically you set up a filtering condition using a Predicate Object and just pass it to the FilterIterator and the iterator returns only those objects for which the predicate evalutes to a true.


public void testFilterIterator() {
ArrayList list = new ArrayList();
list.add("Hello");
list.add("Hello1");
list.add("Hello2");

FilterIterator filterIterator = new FilterIterator(list.iterator(), new FilterPredicate());

for (;filterIterator.hasNext();) {
String s = (String) filterIterator.next();
assertEquals("Hello", s); // only "Hello" is returned
assertEquals(3, list.size()); // non destructive filtering
}
}

// the Predicate object. pretty simple
public class FilterPredicate implements Predicate {
public boolean evaluate(Object o) {
return ((String) o).equals("Hello");
}
}



To update a collection with only those objects that match the predicate (destructive filtering) we can use CollectionUtils.filter()
Building on the same test as before


public void testDestructiveFilter() {
ArrayList list = setupList();
assertEquals(3, list.size());

CollectionUtils.filter(list, new FilterPredicate());
assertEquals(1, list.size()); // other objects in list are stripped off
}


Similarly if we want to do a non destructive filtering.


public void testNonDestructiveFilterWhichMatches() {
ArrayList list = setupList();

// the select() keeps only those objects that evaluate to a 'true'
Collection newCollection = CollectionUtils.select(list, new FilterPredicate());
assertEquals(3, list.size());
assertEquals(1, newCollection.size());
}

public void testNonDestructiveFilterWhichDoesNotMatches() {
ArrayList list = setupList();

// I guess U know what this means by now :)
Collection newCollection = CollectionUtils.selectRejected(list, new FilterPredicate());
assertEquals(3, list.size());
assertEquals(2, newCollection.size());
}



using a Transformer
- used to perform a tranformation on each object in a collection


public void testBasicTransformer() {
final ArrayList list = setupList();

CollectionUtils.transform(list, new StringTransformer());
assertEquals("HELLO", list.get(0)); // "HELLO" converted to upper case
}

// my transformer class which converts to Upper Case
private static class StringTransformer implements Transformer {
public Object transform(Object o) {
return StringUtils.upperCase((String) o);
}
}


We can also chain transformers to do some pretty neat stuff.

We can also use Predicates to count number of objects in a Collection if we need to count depending upon a condition


// the Predicate used here returns 'true' only for "Hello" objects in the collection
public void testCountingNumberOfHellosInCollection() {
ArrayList list = setupList();
assertEquals(1, CollectionUtils.countMatches(list, new FilterPredicate()));
}



There are tons of other juicy bits hidden away. Explore maadi.

5 Comments:

Post a Comment

<< Home