Functional Style Programming in Java -List Transformation
I have been reading a lot of posts on functional style programming and its amazing how things can be simplified by using functional style of programming.
I find it hard to get my head around a lot of the functional programming concepts like Monad and Functors.
I seem to understand what they are when I read articles on them but I keep forgetting in a few days time and I have to start over again. Perhaps the problem is that I haven’t been able to find use cases for them in my everyday programming which happens to be Java mostly and javascript and PHP occasionally.
Javascript is actually great for functional style programming as Functions are first-class citizens in Javascript.
But recently I actually managed to apply a little functional style programming to solve a recurring task in a java application I’m working on.
I need to transform full-blown objects into combo-box friendly objects that I can transform into JSON object and send it to webpages for use in forms.
Let’s take an example of a Person object. The drop-down box for person should have person’s id as value and
for display text it should be a combination of surname and name.
For ease of use for getting display text let’s say we have a Person class that returns name and surname combination through its toString() method.
So, here’s our person class.
class Person {
private Integer id;
private String name;
private String surname;
// other interesting properties
..........
// getters and setter methods
........
.....
public String toString(){
return surname+", "+name;
}
}
And I have a class called Combovalue.
class Combovalue {
Integer value;
String label;
public ComboValue(Integer value, String label){
this.value=value;
this.label=label;
}
// getters and setters
.........
}
Now that we necessary classes we need a handy way to map a List of Person to a List of comboValues.
For that we’ll use a Utility class for mapping and an interface that has a method to do the transformation .
First is class ListMap which has a static method which takes a list of Type A objects and returns a List of Type B object.
Well, for our example, the method should take a list of Person and return a List of ComboValue.
And we need an interface that has a method that takes an argument of type A and returns an object of type B.
Of course for our example it should take a person and return a ComboValue.
Here’s the interface that should be implemented to do the object transformation. Its not really transformation per se, but let’s call it that for simplicity.
It takes a parameter of type A and return a value of type B.
public interface ITransformer<A,B> {
public B transform(A value);
}
Here’s the class whose static method transforms a list of type A to list of type B.
public class ListMap {
public static <A, B > List<B> map( List<A> list, ITransformer<A,B> f ){
List<B> values= new ArrayList<B>();
for( int i=0; i<list.size();i++){
values.add( f.transform(list.get(i)) );
}
return values;
}
}
Now the usage:
Say we have a method in one of our classes in our application that handles this transformation.
It retrives a list of Person from database, passes it to the map() method of ListMap serialize it into JSON and returns it.
Class JSONService{
XStream xstream ;
public JSONService(){
xstream = new XStream(new JettisonMappedXmlDriver());
}
public String getPersonCombos(){
//Assume we have a DAO class to retrieve data for us as List.
List<Person> list= pesonDao.getList();
//now the magic
List<ComboValue> combos = ListMap.map(list, new ITransformer<Person, ComboValue>() {
public ComboValue transform(Person person) {
return new ComboValue(person.getId(), person.toString());
}
});
//use XStream to serialize the list into JSON data.
return xstream.toXML(combos)
}
}
That’s alll the magic.
Transforming object by object can be a pain in the back-side. And the above technique is hardly that useful.
As we’ll end up creating methods for each domain to return combo data. And if we have say over 50 domain objects its a pain. And the above abstraction doesn’t ease our pain much
So, Say we define an interface called Entity that has a single method.
public interface Entity {
public Integer getId();
}
Our person class and all our Domain classes implement this interface.
and our Person class becomes:
class Person implements Entity {
// the rest is unchanged
}
now lets modify our JSONService class.
Class JSONService{
XStream xstream ;
public JSONService(){
xstream = new XStream(new JettisonMappedXmlDriver());
}
public String getCombo( Class clazz){
//Assume we have a DAO factory with a method that returns a DAO object for a given class to retrieve data for us as List.
List<clazz> list= DAOFactory.get(clazz).getList();
//Since all our domain classes implement Entity interface we pass in the argument type as Entity
List<ComboValue> combos = ListMap.map(list, new ITransformer<Entity, ComboValue>() {
public ComboValue transform(Entity entity) {
return new ComboValue(entity.getId(), entity.toString());
}
});
//use XStream to serialize the list into JSON data.
return xstream.toXML(combos)
}
}
And now we have a nice way of transforming any entity into ComboValue object and returning it as JSON !
With Java Generics and a bit of inspiration from functional programming we have a reusable classes that forms a component that will always obey the fundamental rule of returning List of type B for any supplied list of type A.
Hardly rocket science, but useful piece of abstraction nevertheless.