Functionals - Toolbox

Functionals? Well. Almost.

Current topic is the AppCollections (and its friends) and package eu.qualityontime.functionals.

AppCollections

It is a utility function collection of some collection related fuctions. It can be called helper class.

  1. simple wrapper around existing helper methods (mostly related to functional helpers)
  2. factory methods of certain collection implementations: Map(), IMap() etc.
  3. functional helpers: sort, find, etc.
  4. non existing helpers or null-save helpers: e.g.: isEmpty

Factory methods

Example: Map(), IMap(), List(), IList()

One of the most boring programming task is to write and read something like new ArrayList<Some>(). It is full of noise:

Alternatives: Guava have similar factory methods in Maps, Lists, etc classes. But I do prefer List over newArrayList() and IList(...) over ImmutableList.of(...).

The advantages of using simple factory method is trivial once you are composing them:

1  Map<String, Foo>  t1= new HashMap<>();
2  t1.put("some", ....);
3  List<Some> temp = new ArrayList<Some>();
4  temp.add(...)
5  ...
6  Other o = new Other();
7  o.setSomes(temp);
8  return o;

vs.

1  Other o = new Other();
2  o.setSomes(List(Map("some", ...),...));
3  return o;

Non-existing helpers

Simplest example: isEmpty

Implementation:

1  public static boolean isEmpty(Collection<?> coll) {
2    return (coll == null || coll.isEmpty());
3  }

There is no trick. There is no any special code behind. It is simply as it is: null save helpers which does not exists in standard JDK.

Alternatives: Commons Collections has similar functionality. But it is possible that you do not want to have certain dependencies when you plan to use a few helper method only.

On the other hand dependencies like Commons Collections , Commons Lang , Guava are never “real” dependencies. They are just extensions on the weak JDK java.util package.

Functional helpers

Once you get used to Functional Programming paradigm you will change your style of code. For more info you must read Guava Explained . Similar implementation is available in Commons Collections too.

But why do I need wrapper?

First of all you do not need it. You should develop a small wrapper around collections and using it. See later in description of package eu.qualityontime.functionals.

If you are not developing any wrapper you still have some advantages over using “plain” libraries. (even if I have reasoned against in the previous section).

Functional package

Package eu.qualityontime.functionals:

F prefix means functional. All these classes are wrapper around the appropriate type and delgate all method call. And as an addition it is extending them by few useful functional stuff.

What does the following code do?

 1  List<Todo> todos = ...
 2  Predicate<Todo> completed = ...
 3  Function<Todo, List<User>> assignedUsers = ...
 4  Function<User, Long> nationality_id = ...
 5  Function<User, Map<String, Object>> to_map = ... 
 6  Function<Long, String> to_string = ...
 7  ...
 8  //and the magic
 9  Map<String, Collection<Map<String,Object>> = FIterable(todos) //FIterable<Todo>
10    .filter(completed) //FIterable<Todo>
11    .flatMap(assignedUsers) //FIterable<User>
12    .groupBy(nationality_id) //FMultimap<Long, User>
13    .transformValues(to_map) //FMultimal<Long, Map<String, Object>>
14    .asMap() //FMap<Long, Collection<Map<String,Object>>
15    .mapKeys(to_string);//FMap<String, Collection<Map<String,Object>>

Do you really have any difficulties to understand (even without comments)? Simply beautifull!


I will never again develop it
Jun 11, 2014
comments powered by Disqus

Links

Cool

RSS