28 June 2010

Build a map of lists of calendar from a list of strings

Valid since: op4j 1.0

Description
Convert a List<String> to a List<Calendar>, filter the result by keeping only the elements belonging to the year 2010 and, finally, create a Map<Integer,List<Calendar>> with the month as key. Finally, what we get are the dates belonging to 2010 grouped by month.

Scenario
Our List<String> asString variable contains some strings representing dates:

asString == {"20100505", "20100614", "19980407",
"20100209", "20100215", "20110101",
"20100620", "20100301"}

Some of the dates represented by these strings do not belong to the year 2010 so, once they are converted to Calendar, we'll have to filter them in order to keep only the 2010 dates. With these filtered results we'll create the Map<Integer,List<Calendar>> result variable which will be:

Map<Integer, List<Calendar>> result ==
[{1, {20100209, 20100215}},
{2, {20100301}},
{4, {20100505}},
{5, {20100614, 20100620}}]

Recipe
Steps:
1. Iterate the list and, for each element, create the Calendar it represents (we assume all of the elements are convertible to Calendar, otherwise, we should filter them).
2. Filter the List<Calendar> by removing all the dates not between January, 1st and December, 31st.
3. Create a Map<Integer, List<Calendar>> with the 2010 dates using the date month as the key.

op4j funcions involved:
  • FnString.toCalendar(pattern): converts a String into a Calendar.

  • FnObject.lessThan(object): compares two comparable elements and returns true if the target is less than the object passed.

  • FnObject.greaterOrEqTo(object): compares two comparable elements and returns true if the target is greater or equal to the object passed.

  • Call.methodForInteger(method, parameters, ...): calls a method on the target element and returns the result of that call.

Let's see it coded with op4j:

Map<Integer, List<Calendar>> result = Op.on(asString).forEach()
.exec(FnString.toCalendar("yyyyMMdd")).endFor()
.removeAllTrue(FnObject
.lessThan(new DateTime(2010, 1, 1, 0, 0, 0, 0)
.toCalendar(Locale.getDefault())))
.removeAllTrue(FnObject
.greaterOrEqTo(new DateTime(2011, 1, 1, 0, 0, 0, 0)
.toCalendar(Locale.getDefault())))
.zipAndGroupKeysBy(Call
.methodForInteger("get", Calendar.MONTH)).get();

3 comments:

  1. I have posted a question on the user forum for op4j. Not sure if you are aware of it. Can you kindly respond. The link is http://sourceforge.net/apps/phpbb/op4j/viewtopic.php?f=2&t=12

    Thanks,
    Ganesh.

    ReplyDelete
  2. You've been answered ;-)

    Regards,
    Daniel.

    ReplyDelete
  3. Thanks for your answer daniel. I thanked u in the forum as well. BTW, I have posted another question there... http://sourceforge.net/apps/phpbb/op4j/viewtopic.php?f=2&t=13

    Appreciate ur help in advance.

    ReplyDelete