Thursday, 25 June 2015

Strategy Pattern in Java 8

These are two examples on how to implement a Strategy pattern design using Java 8 functional style together with Cyclops pattern matching and Hamcrest libraries.

PrintDependingOnInput method is a strategy that will System.println some message based on the log passed.

AddPrefix is another strategy that will add a prefix to a message based on the message content.

package com.marco.patternmatching; 

 

import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
import static org.hamcrest.core.AllOf.allOf;
import java.util.ArrayList;
import java.util.List;
import com.aol.cyclops.matcher.builders.Matching; 

 

public class FunctionalStrategy {

  public static void main(String[] args) {
     List<String> toTest = new ArrayList<>();
     toTest.add("INFO everything is fine");
     toTest.add("WARN something weird happened");
     toTest.add("ERROR NullPointerException");
     toTest.add("ERROR IOException");
     
     toTest.stream().forEach(FunctionalStrategy::printDependingOnInput);

     System.out.println("--------------------");

     List<String> messages = new ArrayList<>();
     messages.add("everything is fine");
     messages.add("something weird happened");
     messages.add("NullPointerException");
     messages.add("IOException");

     messages.stream().map(FunctionalStrategy::addPrefix).forEach(System.out::println);
  }

        
  public static void printDependingOnInput(String log) {

     Matching
        .when().isMatch(startsWith("INFO"))
                   .thenConsume(System.out::println)
        .when().isMatch(startsWith("WARN"))
                   .thenConsume(message -> System.out.println("Found one warning : " + message))
        .when().isMatch(allOf(startsWith("ERROR"), containsString("NullPointerException")))
                   .thenConsume(message -> System.err.println(message))
        .when().isMatch(allOf(startsWith("ERROR"), containsString("IOException")))
                   .thenConsume(message -> System.err.println(message + " Retrying a couple of times"))
        .match(log);

   }

   public static String addPrefix(String log) {

     return Matching
        .when().isMatch(allOf(not(containsString("Exception")), not(containsString("weird"))))
                    .thenApply(message -> "INFO " + message)
        .when().isMatch(containsString("weird"))
                    .thenApply(message -> "WARN " + message)
        .when().isMatch(containsString("Exception"))
                    .thenApply(message -> "ERROR " + message)
        .match(log).get();

  }
}


Nice and clean ;)

Tuesday, 16 June 2015

Java 8 and how Optional removes the need for == null

I was confused initially when the Optional concept entered the Java world.
I was wondering how the hell can Optional remove the need to check for null? At some point I will need to use optional.isPresent() before using whatever is inside. So what's the point to replace == null with isPresent()?


The main concept to keep in mind is that Optional is a monad and as a monad contains map(), flatmap(), filter() and other methods that can be used directly against the optional instance.


Here, with the following simple code, I hope I will clarify a bit more the power of java.util.Optional.

In this example we have a list of logs and we want to apply 3 different operations based on the the type of log (INFO, ERROR, WARN).


package com.marco.optional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class TestOptional {

        public static void main(String[] args) {
                List<Optional<String>> logs = new ArrayList<Optional<String>>();
                logs.add(Optional.ofNullable("INFO:: some info here 1"));
                logs.add(Optional.ofNullable("INFO:: some info here 2"));
                logs.add(Optional.ofNullable("ERROR:: some error here 3"));
                logs.add(Optional.ofNullable("INFO:: some info here 4"));
                logs.add(Optional.ofNullable("WARN:: some info here 5"));
                logs.add(Optional.ofNullable(null));
                logs.add(Optional.ofNullable("INFO:: some info here 7"));
                logs.add(Optional.ofNullable("WARN:: some info here 8"));

                for (Optional<String> singleLog : logs) {
                        printErrors(singleLog);
                        printInfos(singleLog);
                        printWarnOnlyNumber(singleLog);
                }

        }

        public static void printErrors(Optional<String> singleLog) {
                singleLog.filter(entry -> entry.startsWith("ERROR")).ifPresent(System.out::println);
        }

        public static void printInfos(Optional<String> singleLog) {
                singleLog.filter(entry -> entry.startsWith("INFO")).ifPresent(System.out::println);
        }

        public static void printWarnOnlyNumber(Optional<String> singleLog) {
                singleLog.filter(entry -> entry.startsWith("WARN"))

                          .map(warn -> warn.substring(warn.length() - 1))

                          .ifPresent(System.out::println);
        }
}

Output :


INFO:: some info here 1
INFO:: some info here 2
ERROR:: some error here 3
INFO:: some info here 4
5
INFO:: some info here 7
8


No == null and no if

Optional takes care of it for you ;)

Friday, 12 June 2015

Java 8, easier with Cyclops : Try


Cyclops is another promising open source library from John McClean in AOL, that aims to extends and simplify Java 8 functionality.

One of its feature is Try that offers an alternative way to manage exception handling.

Imagine you have a method that load files from some location :

private List<File> loadFiles() { 
     return Lists.newArrayList(new File("somePath_one"), new File("somePath_two"));
} 

Many things could go wrong there, file does not exist, network is down, etc.
 
Traditionally, we could have manage exceptions surrounding the loadFiles() method with try and catch and handle each exception within a catch statement.

Cyclops Try made things easier and cleaner :

Try.withCatch(this::loadFiles, Exception.class)


    .onFail(FileNotFoundException.class, e -> System.err.println("Something specific to do here if file does not exists" + e))


    .onFail(IOException.class, e -> System.err.println("Maybe retry a couple of times before dropping the operation" + e))


    .forEach(System.out::println);

Based on the exception, different functions can be triggered.

http://media.giphy.com/media/U0uowJVj7ewO4/giphy.gif

Thursday, 11 June 2015

10 team building tips

1) Good Morning


http://media.giphy.com/media/RbVOveSAHkk2A/giphy.gif

When you enter in the office, before sitting on your desk, smile and say good morning to the team. Yes, E V E R Y day.

2) Listen when someone is talking to you.

http://media.giphy.com/media/kwNSxdqqutsEE/giphy.gif

When a team member is talking to you, look him in the eyes and show interest in what he is saying.

3) Give space, build trust


http://media.giphy.com/media/HdsLiowsPuoso/giphy.gif

Let team member fail sometimes and repair from their failures.
You may be always right, but who cares?! Other people need to learn to fail and take responsibilities.


4) Connect


http://media.giphy.com/media/LPAohuvTif0ek/giphy.gif

Go and take a coffee with each person in the team separately.

5) Congratulate


http://media.giphy.com/media/IAFlOwj4XsNlm/giphy.gif

When someone does something good, tell her/him!

6) Keep your personal problems out of work.


 http://media.giphy.com/media/dIDae8s93pave/giphy.gif

Don't shout at people because your last evening was bad.

7) Do pair programming


http://media.giphy.com/media/ggKMDmjkGZ5ZK/giphy.gif

Great way to share knowledge and build solid work relationships.

8)  Feedback


http://media.giphy.com/media/ql89wsWoAgTAI/giphy.gif

Do code reviews without sounding the king of the programming universe. Explain in a calm and friendly tone whatever you want to say.

9) Have lunch together


http://media.giphy.com/media/PvBnBEr7CUUDK/giphy.gif

If possible go regularly to lunch with as many team members as possible.


10) See you tomorrow


http://media.giphy.com/media/77ggDHDT372j6/giphy.gif

When you leave in the evening, if you are not the last person in the team left, say goodbye.


Thursday, 4 June 2015

Memoize functions in java 8

Memoization is not a grammar error,  memoization is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.

http://en.wikipedia.org/wiki/Memoization

I will explain it with a simple example.

Context :

Table PIZZA, columns ID, NAME

We have a java function called "hereThePizzaGiveMeTheId" where you pass a String representing a pizza name and it will return the correspondent id retrieved from the DB.

Function<String, Integer> hereThePizzaGiveMeTheId = name -> {

            int pizzaId = -1;


            System.out.println("Select ID from PIZZA where name = '" + name + "'");

            pizzaId = pizzaDao.get(name);


            return pizzaId;

        };

Now, if I call this function with the same pizza name I will hit the DB each time :

        System.out.println(hereThePizzaGiveMeTheId.apply("Margherita"));
        System.out.println(hereThePizzaGiveMeTheId.apply("Margherita"));
        System.out.println(hereThePizzaGiveMeTheId.apply("Margherita"));
        System.out.println(hereThePizzaGiveMeTheId.apply("Margherita"));
        System.out.println(hereThePizzaGiveMeTheId.apply("Four Season"));
        System.out.println(hereThePizzaGiveMeTheId.apply("Four Season"));
        System.out.println(hereThePizzaGiveMeTheId.apply("Four Season"));
        System.out.println(hereThePizzaGiveMeTheId.apply("Four Season"));
        System.out.println(hereThePizzaGiveMeTheId.apply("Gorgonzola and figs"));
        System.out.println(hereThePizzaGiveMeTheId.apply("Gorgonzola and figs"));
        System.out.println(hereThePizzaGiveMeTheId.apply("Gorgonzola and figs"));
        System.out.println(hereThePizzaGiveMeTheId.apply("Gorgonzola and figs"));


OUTPUT:


Select ID from PIZZA where name = 'Margherita'
1
Select ID from PIZZA where name = 'Margherita'
1
Select ID from PIZZA where name = 'Margherita'
1
Select ID from PIZZA where name = 'Margherita'
1
Select ID from PIZZA where name = 'Four Season'
2
Select ID from PIZZA where name = 'Four Season'
2
Select ID from PIZZA where name = 'Four Season'
2
Select ID from PIZZA where name = 'Four Season'
2
Select ID from PIZZA where name = 'Gorgonzola and figs'
3
Select ID from PIZZA where name = 'Gorgonzola and figs'
3
Select ID from PIZZA where name = 'Gorgonzola and figs'
3
Select ID from PIZZA where name = 'Gorgonzola and figs'
3



Fantastic, but I don't want to run that function every time, if I already know the result based on the pizza name.
So, lets memoize (cache) the result of that function.

First we create a generic method that wraps a function into another function that will behave the same as the input one, but will check if the result is already computed : 

public static <X, Y> Function<X, Y> memoise(Function<X, Y> fn) {

        Map<X, Y> pp = new ConcurrentHashMap<X, Y>();

        return (a) -> pp.computeIfAbsent(a, fn);

    }


 Then we wrap our "hereThePizzaGiveMeTheId"  function :

Function<String, Integer> memoziedHereThePizzaGiveMeTheId = memoise(hereThePizzaGiveMeTheId);
 
Lastly, we call again the same logic as before, but using the new memoziedHereThePizzaGiveMeTheId function :

      
        System.out.println(memoziedHereThePizzaGiveMeTheId.apply("Margherita"));

        System.out.println(memoziedHereThePizzaGiveMeTheId.apply("Margherita"));

        System.out.println(memoziedHereThePizzaGiveMeTheId.apply("Margherita"));

        System.out.println(memoziedHereThePizzaGiveMeTheId.apply("Margherita"));

        System.out.println(memoziedHereThePizzaGiveMeTheId.apply("Four Season"));

        System.out.println(memoziedHereThePizzaGiveMeTheId.apply("Four Season"));

        System.out.println(memoziedHereThePizzaGiveMeTheId.apply("Four Season"));

        System.out.println(memoziedHereThePizzaGiveMeTheId.apply("Four Season"));

        System.out.println(memoziedHereThePizzaGiveMeTheId.apply("Gorgonzola and figs"));

        System.out.println(memoziedHereThePizzaGiveMeTheId.apply("Gorgonzola and figs"));

        System.out.println(memoziedHereThePizzaGiveMeTheId.apply("Gorgonzola and figs"));

        System.out.println(memoziedHereThePizzaGiveMeTheId.apply("Gorgonzola and figs"));



OUTPUT:

Select ID from PIZZA where name = 'Margherita'
1
1
1
1
Select ID from PIZZA where name = 'Four Season'
2
2
2
2
Select ID from PIZZA where name = 'Gorgonzola and figs'
3
3
3
3







We will hit the DB only if the result of the function is not already present in the map.

That's it.

p.s.

Gorgonzola and figs is a fantastic pizza :















Thursday, 14 May 2015

Simple benchmarking : Immutable Collections VS Persistent Collections

Often you need to add new elements to a collection.
Because you are a good and careful developer you want to keep things immutable as much as possible. So adding a new element to an immutable collections will mean that you have to create a new immutable collection that contains all the elements of the original collections plus the new element.

You can create immutable collections using the guava library and also using the recent pCollection library.

In the following example, we will build 2 immutable lists, one immutable from guava and one persistent from pCollection.

They both will contain 10.000 integers initially.

We will create 20.000 immutable lists one for each type and we will measure the time taken.


package com.marco.pcollections;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.pcollections.PCollection;
import org.pcollections.TreePVector;
import com.google.common.collect.ImmutableList;

public class PcollectionVSImmutable {
 public static void main(String[] args) {
  
  List<Integer> bigList = new ArrayList<Integer>();
  for (int i = 0; i < 10000; i++) {
   bigList.add(new Integer(i));
  }
  
  Map<Integer, ImmutableList<Object>> allImmutable = new HashMap<Integer, ImmutableList<Object>>();
  Map<Integer, PCollection<Integer>> allPersistent = new HashMap<Integer, PCollection<Integer>>();
  
  
  
  PCollection<Integer> persistent = TreePVector.from(bigList);
  long start = System.currentTimeMillis();
  for (int i = 10000; i < 30000; i++) {
   allPersistent.put(new Integer(i), persistent.plus(new Integer(i)));
  }
  System.out.println("creating 20.000 pCollections takes : " + (System.currentTimeMillis() - start) + "ms");
  
  
  ImmutableList<Integer> immutable = ImmutableList.copyOf(bigList);
  start = System.currentTimeMillis();
  for (int i = 10000; i < 30000; i++) {
   allImmutable.put(new Integer(i), ImmutableList.builder().addAll(immutable).add(new Integer(i)).build());
  }
  System.out.println("creating 20.000 Guava ImmutableList takes : " + (System.currentTimeMillis() - start) + "ms");
  
  System.out.println("All immutable size : " + allImmutable.size() + " allPersistent size : " + allPersistent.size());
 }
}


Output :

creating 20.000 pCollections takes : 29ms
creating 20.000 Guava ImmutableList takes : 18347ms
All immutable size : 20000 allPersistent size : 20000

Monday, 11 May 2015

Immutable Objects with Lombok - workshop

An immutable object is an object whose state cannot be modified after it is created.


Why Immutable Objects are important?


Because you have no total control : objects can be passed anywhere and can arrive from anywhere  in the code. If they are mutable, then any object can modify their state. Different threads can access the same model object and modify/read its state creating many problems difficult to handle.

What is an Immutable object?


Final private fields,  No Setters & Unmodifiable collections

An example ?



What does Lombok?


Project Lombok aims to reduce boilerplate codes by replacing them with a simple set of annotations.

How to install Lombok?


see here : https://projectlombok.org/download.html


Workshop :

Create a model object called Home with the following fields :   

String address;
The street name of your home

int age;
How old were you when you enter this house


int fromYear;
Which year you start living there
int toYear;
Which year you left


Create a toString() method to print the details.




Create a class called MyHomes that prints the list of Homes you lived in.   

This class should create as many homes you lived in and print the details for each one of them. 


Now make the class immutable

Now try to clean the Home class code with Lombok!!

Hints / Immutability support :-

val
@AllArgsConstructor
@Builder
@Value
@FieldDefaults



 
 How can we change a value? 

Add an immutable boolean field to indicate if the address has been verified.

Default should be false.

Add a method to MyHomes to verify a List of Homes


 Now try to use the @Wither annotation from Lombok!!




End of the workshop











Stretch content