quinta-feira, 20 de março de 2014

4 Real World Lambdas with Collections examples

I love functional programming and I'm exciting not only about Lambda, but also about the stream API  and the new functional interfaces that comes with Java 8, which was released recently. In the next lines I'll show some codes I took from some Java projects in github and rewrote it using Java 8. Notice obviously I had to mock some classes just to focus on the code rewrite.

If you find a better way to do this, please let me know!

Code on Github



1) Concatenating a List into a String


Original


public static String matrixparamtest(PathSegment id){
         StringBuffer sb = new StringBuffer();
         sb.append("matrix=");
         sb.append("/" + id.getPath());
         Map matrix = id.getMatrixParameters();
         Set keys = matrix.keySet();
         for (Object key : keys)
         {   
            sb.append(";" + key.toString() + "=" +
                    matrix.get(key.toString()));

         }   
         return sb.toString();
} 

My Java 8 Equivalent:


public static String matrixparamtestlambda(PathSegment id){
        Map matrix = id.getMatrixParameters();
        String keys = matrix.keySet().stream()
                    .map(k -> k + "=" + matrix.get(k))
                    .collect(Collectors.joining(";", ";", ""));
        return "matrix=/" + id.getPath() + keys;

}

What's going on here?

Take the Stream from the keys: matrix.keySet().stream()
Map to a Stream with format "param=val":  map(k -> k + "=" + matrix.get(k)
Join the stream into a big string starting with ";" and separated by ";": collect(Collectors.joining(";", ";", ""))


2) Mapping not null elements from a List

Original

public static Map mapElements(){
        final Map map = new HashMap();
        for (final Element element : values()) {
                final String name = element.getLocalName();
                if (name != null)
                        map.put(name, element);
        }   
        return map;  
}    

My Java 8 Equivalent:

public static Map mapElementsLambda(){
        return values().stream()
                .filter(e -> e.getLocalName() != null)
                .collect(Collectors.toMap(Element::getLocalName, e -> e));
}

What's going on here?

Taking the stream object from values: values().stream()
Filtering them to avoid null values: filter(e -> e.getLocalName() != null)
Collecting a map using as the key the localName attribute and as value the element itself: collect(Collectors.toMap(Element::getLocalName, e -> e));

3) Transforming a Map

Original

public static Map filterLoadedValues(Map in) {   
        Map out = new HashMap<>();
        for (Iterator iterator = in.entrySet().iterator(); iterator.hasNext();){   
                Map.Entry entry = (Map.Entry) iterator.next();
                out.put(entry.getKey().toString(), Float.valueOf(entry.getValue().toString()));
        }   
        return out;
}

My Java 8 Equivalent:

public static Map filterLoadedValuesLambda(Map in) {   
        return in.entrySet().stream().collect(
                        Collectors.toMap(
                                e -> e.getKey().toString(),
                                e -> Float.valueOf(e.getValue().toString())    
                )); 
} 

What's going on here?


  • We are taking a Stream of the entries of the map: in.entrySet().stream()
  • Collecting the entries: collect
  • Generating a new one a transforming the value from String to Float: Collectors.toMap( e -> e.getKey().toString(),e -> Float.valueOf(e.getValue().toString()) ;

4) Summing

Original

public static float getTotalPrice() {
        float totalPrice = 0;
        if (lineItems != null) {
                for (LineItem item : lineItems) {
                        if (item.getPrice() != null)
                                totalPrice += item.getPrice();
                }   
        }   
        return totalPrice;
}  

My Java 8 Equivalent:

public static double getTotalPriceLambda() {
        return lineItems.stream().mapToDouble(LineItem::getPrice).filter(Objects::nonNull).sum();
} 

What's going on here?

  • Map the stream to a DoubleStream: mapToDouble(LineItem::getPrice)
  • Filter the Stream and remove possible null values: filter(Object::nonNull)
  • Sum all the elements: sum();

Conclusion

Java 8 brings lots of advantages to programming when dealing with lists. As you can see, I took code from "real world" and not sample applications to demonstrate Lambda. It shows that Lambda brings productivity to our daily code.


Nenhum comentário:

Postar um comentário