So I posted last time about filtering Java Collections using a "functional" approach. Today I'll look at another useful operation - transformation.
This is slightly more complicated than filtering, but not much. The problem this time is to take a List of Object's of some Type, and transform it into a List of Object's of a different Type. For example, convert a List of ReallyComplexObject's to a List of EquallyComplexObject's:
Of course there are many alternative ways to write this. Not least you should factor out the creation of the EquallyComplexObject to a separate method that would be invoked in the for loop. I took a similar approach with transformation that I used for filtering, and arrived at:
Again, the expressiveness of this really shines when you factor the Transformer out into a separate class, or create it in a separate method. Our client code becomes:
To support this the Util class gets a few extra bits and pieces:
Its turned out to be surprisingly useful - i'm already using it in lots of places and finding the results pleasingly readable. The biggest gain, to my mind, is that you get to code at a higher level of abstraction because in each case you don't have to think about the mechanics of iterating the original List's.
Yes I know its ridiculously simple to iterate a for loop, and where the predicate or transformation is simple the alternative presented here appears to have dubious value, but somehow making a "Filter" or a "Transformer" that focuses on how to filter or transform just one object is ... well, its transformative. Try it, you might like it :)
My Blog has moved to Github Pages
Showing posts with label functional. Show all posts
Showing posts with label functional. Show all posts
Monday, 4 October 2010
Transforming Java Collections
Saturday, 2 October 2010
Filtering Java Collections
OK, its my first ever blog post, so no laughing - gotta start somewhere, right? It doesn't help that the cat is tap-dancing on my keyboard at every opportunity.
Anyways, I recently made a couple of handy utility methods and classes for filtering and transforming java.util.List's (well, Iterable's actually), using a more functional approach, which I thought I'd describe. For a first-post I thought i'd start with filtering. (I know, I know, Google-collections / Guava ... hey I like programming for programming's sake ok?).
The basic problem is: you have a List of Objects of some type, and you want to create a new List containing a subset of the original, where some objects are removed based on some properties of those Objects. To make the example concrete lets say we have a list of Strings (List<String>) and we want to remove any String with length less than 3 characters. The obvious way to do it is:
Short and simple, but not particularly pretty, readable or re-usable. Lets not forget that here the predicate or "test" is simple - as the complexity of the predicate grows, so the readability of this implementation declines. A natural next step with a more complex predicate would, of course, be to factor the predicate out into a separate method.
One thing that certainly doesn't feel right is that the predicate is actually expressed as an inverse of the intended behaviour - it basically says "if the string has at least 3 characters, keep it".
Anyway, after filtering a few lists with code similar to this, I decided to factor it out into something that's a little more re-usable, makes it easier to express the intent, and thus makes the code more readable. First, lets look at what the same operation would look like using the utility code, then we'll get to the utility itself:
Now that's a little more wordy, largely because of Java's lack of closure's, but that's a topic for another post :). What I do like about it is that the intent is expressed more clearly - "filter", "remove", aString.length() < 3.
We could make it clearer by writing the Filter implementation as a separate top-level (or nested) class, instead of an anonymous one:
Alternatively we can achieve similar clarity with an anonymous inner class by factoring out the creation of that class into a separate method:
Here the slightly unconventional method name "stringsShorterThan" helps readability in the calling code.
I put the utility code for this into a little class where we were already gathering some other general utility methods, innovatively called "Util". It looks something like this:
Unsurprisingly that's just the code we started with, factored out into a utility method that ever-after lets you provide just the predicate for removal, wrapped in a little boiler plate. If the predicate is complex, or frequently needed, you can factor it out into a top-level class, create a test-case for it, and benefit from re-use.
Anyways, I recently made a couple of handy utility methods and classes for filtering and transforming java.util.List's (well, Iterable's actually), using a more functional approach, which I thought I'd describe. For a first-post I thought i'd start with filtering. (I know, I know, Google-collections / Guava ... hey I like programming for programming's sake ok?).
The basic problem is: you have a List of Objects of some type, and you want to create a new List containing a subset of the original, where some objects are removed based on some properties of those Objects. To make the example concrete lets say we have a list of Strings (List<String>) and we want to remove any String with length less than 3 characters. The obvious way to do it is:
Short and simple, but not particularly pretty, readable or re-usable. Lets not forget that here the predicate or "test" is simple - as the complexity of the predicate grows, so the readability of this implementation declines. A natural next step with a more complex predicate would, of course, be to factor the predicate out into a separate method.
One thing that certainly doesn't feel right is that the predicate is actually expressed as an inverse of the intended behaviour - it basically says "if the string has at least 3 characters, keep it".
Anyway, after filtering a few lists with code similar to this, I decided to factor it out into something that's a little more re-usable, makes it easier to express the intent, and thus makes the code more readable. First, lets look at what the same operation would look like using the utility code, then we'll get to the utility itself:
Now that's a little more wordy, largely because of Java's lack of closure's, but that's a topic for another post :). What I do like about it is that the intent is expressed more clearly - "filter", "remove", aString.length() < 3.
We could make it clearer by writing the Filter implementation as a separate top-level (or nested) class, instead of an anonymous one:
Alternatively we can achieve similar clarity with an anonymous inner class by factoring out the creation of that class into a separate method:
Here the slightly unconventional method name "stringsShorterThan" helps readability in the calling code.
I put the utility code for this into a little class where we were already gathering some other general utility methods, innovatively called "Util". It looks something like this:
Unsurprisingly that's just the code we started with, factored out into a utility method that ever-after lets you provide just the predicate for removal, wrapped in a little boiler plate. If the predicate is complex, or frequently needed, you can factor it out into a top-level class, create a test-case for it, and benefit from re-use.
Subscribe to:
Posts (Atom)