SlideShare a Scribd company logo

No more loops with lambdaj

Mario Fusco
Mario FuscoDrools project lead at Red Hat
No more loops with

            λambdaj
An internal DSL to manipulate
  collections without loops

     by Mario Fusco
 mario.fusco@gmail.com
  twitter: @mariofusco
Why is lambdaj born?
The best way to understand what lambdaj
does and how it works is to start asking
why we felt the need to develop it:

  We were on a project with a complex data model
                                                     j
  The biggest part of our business logic did almost
  always the same: iterating over collections of our
  business objects in order to do the same set of tasks
  Loops (especially when nested or mixed with
  conditions) are harder to be read than to be written
  We wanted to write our business logic in a less
  technical and closer to business fashion
What is lambdaj for?
 It provides a DSL to manipulate collections in a
 pseudo-functional and statically typed way.
 It eliminates the burden to write (often poorly
 readable) loops while iterating over collections.
                                                     j
 It allows to iterate collections in order to:


convert
                         aggregate
 filter          index

                      group
          sort                   extract
How does lambdaj work?
lambdaj is a thread safe library of static
methods based on 2 main features:

  treating a collection as it was a single object by
  allowing to propagate a single method invocation
                                                       j
  to all the objects in the collection

forEach(personsInFamily).setLastName("Fusco");

  allowing to define a reference to a java method in
  a statically typed way

sort(persons, on(Person.class).getAge());
The Demo Data Model
Print all cars’ brands
  Iterative version:

StringBuilder sb = new StringBuilder();
                                                             j
for (Car car : cars)
   sb.append(car.getBrand()).append(", ");
String brands = sb.toString().substring(0, sb.length()-2);


  lambdaj version:

String brands = joinFrom(cars).getBrand();
Select all sales of a Ferrari
  Iterative version:

List<Sale> salesOfAFerrari = new ArrayList<Sale>();
for (Sale sale : sales) {
   if (sale.getCar().getBrand().equals("Ferrari"))
                                                             j
        salesOfAFerrari.add(sale);
}



  lambdaj version:

List<Sale> salesOfAFerrari = select(sales,
  having(on(Sale.class).getCar().getBrand(),equalTo("Ferrari")));
Find buys of youngest person

  Iterative version:
Person youngest = null;
for (Person person : persons)
                                                              j
   if (youngest == null || person.getAge() < youngest.getAge())
        youngest = person;
List<Sale> buys = new ArrayList<Sale>();
for (Sale sale : sales)
   if (sale.getBuyer().equals(youngest)) buys.add(sale);


  lambdaj version:
List<Sale> sales = select(sales,having(on(Sale.class).getBuyer(),
   equalTo(selectMin(persons, on(Person.class).getAge()))));
Find most costly sale
    Iterative version:

double maxCost = 0.0;
                                                             j
for (Sale sale : sales) {
     double cost = sale.getCost();
     if (cost > maxCost) maxCost = cost;
}


    lambdaj version:

Sol. 1 -> double maxCost = max(sales, on(Sale.class).getCost());
Sol. 2 -> double maxCost = maxFrom(sales).getCost();
Sum costs where both are males
  Iterative version:

double sum = 0.0;
for (Sale sale : sales) {
                                                                j
   if (sale.getBuyer().isMale() && sale.getSeller().isMale())
        sum += sale.getCost();
}


  lambdaj version:

double sum = sumFrom(select(sales,
   having(on(Sale.class).getBuyer().isMale()).and(
   having(on(Sale.class).getSeller().isMale())))).getCost();
Find age of youngest who
bought for more than 50,000
  Iterative version:
int age = Integer.MAX_VALUE;
                                                               j
for (Sale sale : sales) {
   if (sale.getCost() > 50000.00) {
        int buyerAge = sale.getBuyer().getAge();
        if (buyerAge < age) age = buyerAge;
   }
}
  lambdaj version:
int age = min(forEach(select(sales,
   having(on(Sale.class).getCost(), greaterThan(50000.00))))
   .getBuyer(), on(Person.class).getAge());
Sort sales by cost
  Iterative version:

List<Sale> sortedSales = new ArrayList<Sale>(sales);
Collections.sort(sortedSales, new Comparator<Sale>() {
                                                              j
   public int compare(Sale s1, Sale s2) {
      return Double.valueOf(s1.getCost()).compareTo(s2.getCost());
   }
});


  lambdaj version:

List<Sale> sortedSales = sort(sales, on(Sale.class).getCost());
Extract cars’ original cost
  Iterative version:

List<Double> costs = new ArrayList<Double>();
for (Car car : cars)
                                                          j
    costs.add(car.getOriginalValue());


  lambdaj version:

List<Double> costs =
       extract(cars, on(Car.class).getOriginalValue());
Index cars by brand
  Iterative version:

Map<String, Car> carsByBrand = new HashMap<String, Car>();
for (Car car : cars)
                                                             j
    carsByBrand.put(car.getBrand(), car);


  lambdaj version:

Map<String, Car> carsByBrand =
       index(cars, on(Car.class).getBrand());
Group sales by buyers and sellers
                    (iterative version)

   Person buyer = sale.getBuyer();
   Map<Person, Sale> buyerMap = map.get(buyer);
   if (buyerMap == null) {
        buyerMap = new HashMap<Person, Sale>();
                                                                     j
Map<Person,Map<Person,Sale>> map = new HashMap<Person,Map<Person,Sale>>();
for (Sale sale : sales) {




        map.put(buyer, buyerMap);
   }
   buyerMap.put(sale.getSeller(), sale);
}
Person youngest = null;
Person oldest = null;
for (Person person : persons) {
   if (youngest == null || person.getAge() < youngest.getAge())
        youngest = person;
   if (oldest == null || person.getAge() > oldest.getAge())
        oldest = person;
}
Sale saleFromYoungestToOldest = map.get(youngest).get(oldest);
Group sales by buyers and sellers
                  (lambdaj version)
Group<Sale> group = group(sales,                              j
   by(on(Sale.class).getBuyer()),by(on(Sale.class).getSeller()));
Person youngest = selectMin(persons, on(Person.class).getAge());
Person oldest = selectMax(persons, on(Person.class).getAge());
Sale sale = group.findGroup(youngest).findGroup(oldest).first();
Find most bought car
       (iterative version)
Map<Car, Integer> carsBought = new HashMap<Car, Integer>();
for (Sale sale : sales) {
   Car car = sale.getCar();
   Integer boughtTimes = carsBought.get(car);
                                                              j
   carsBought.put(car, boughtTimes == null ? 1 : boughtTimes+1);
}

Car mostBoughtCarIterative = null;
int boughtTimesIterative = 0;
for (Entry<Car, Integer> entry : carsBought.entrySet()) {
   if (entry.getValue() > boughtTimesIterative) {
        mostBoughtCarIterative = entry.getKey();
        boughtTimesIterative = entry.getValue();
   }
}
Find most bought car
       (lambdaj version)
Group<Sale> group = selectMax(
   group(sales, by(on(Sale.class).getCar())).subgroups(),
   on(Group.class).getSize());
Car mostBoughtCar = group.first().getCar();
                                                            j
int boughtTimes = group.getSize();
How does lambdaj work?
 The getCar() invocation is propagated by the first proxy to all the
 sales. The cars returned by these invocations are put again in a
 list and another proxy, similar to the first one, is created to wrap
 this list, allowing to repeat this type of invocation once more
 (proxy concatenation).
                                                                      j
            Car fastestCar = max(

                    forEach(sales).getCar(),

A proxy wraps the          on(Car.class).getSpeed());
list of sales. The
returned object is of
class Sale but             A proxy of the Car class is created in
dynamically                order to register the invocations on it.
implements the             These invocations will be then
Iterable interface too     reapplied to the cars of the former list
Lambdaj’s extensibility
List<Double> speeds = extract(cars, on(Car.class).getSpeed());


                      is the short form for:
                                                               j
List<Double> speeds = convert(cars, new Car2SpeedConverter());


          where the Car2SpeedConverter is defined as:

class Car2SpeedConverter implements Converter<Car, Double> {
    public Double convert(Car car) {
        return car.getSpeed();
    }
}
Performance analysis
Minimum, maximum and average duration in
milliseconds of 20 runs with 100,000 iterations of the
former examples
                                           iterative                    lambdaj
                                   min        max      avg      min       max      avg       ratio
PrintAllBrands                       265        312      283    1,310     1,591    1,377    4.866
FindAllSalesOfAFerrari               281        437      366    1,528     1,607    1,566    4.279
FindAllBuysOfYoungestPerson        5,585      5,975    5,938    6,895     6,989    6,936    1.168
FindMostCostlySaleValue              218        234      227      655       702      670    2.952
SumCostsWhereBothActorsAreAMale      358        452      375    2,199     2,637    2,247    5.992
AgeOfYoungestBuyerForMoreThan50K   5,257      5,319    5,292    9,625     9,750    9,696    1.832
SortSalesByCost                    1,388      1,482    1,448    3,213     3,245    3,231    2.231
ExtractCarsOriginalCost              140        156      141      234       249      236    1.674
IndexCarsByBrand                     172        203      186      327       343      336    1.806
GroupSalesByBuyersAndSellers       9,469      9,766    9,507   12,698    12,838   12,753    1.341
FindMostBoughtCar                  3,744      3,884    3,846    4,181     4,259     4211    1.095


                                                                   Average ratio =         2.658
Known limitations
  Lack of reified generics     lambdaj cannot
  infer the actual type to be returned when a
  null or empty collection is passed to forEach()

List<Person> persons = new ArrayList<Person>();
                                                              j
forEach(persons).setLastName("Fusco");
      Exception

  Impossibility to proxy a final class
  the on() construct cannot register an
  invocation after a final Class is met

List<Person> sortedByNamePersons =
   sort(persons, on(Person.class).getName().toLowerCase());
      Exception
Let’s write it fluently

Fluent                    j
 Interface
  Collections
Why Fluent Interfaces
List<Person> richBuyersSortedByAge =
    sort(
        extract(
            select(sales,
                 having(on(Sale.class).getValue(),
                 greaterThan(50000)))
                                                             j
       ), on(Sale.class).getBuyer()
    ), on(Person.class).getAge());



List<Person> richBuyersSortedByAge = with(sales)
    .retain(having(on(Sale.class).getValue(),greaterThan(50000)))
    .extract(on(Sale.class).getBuyer())
    .sort(on(Person.class).getAge());
LambdaCollections
 LambdaCollections implement the                  java.util.List
 corresponding Java interface (i.e.        add()
                                                          implements
 LambdaList is a java.util.List) so you
 can use them in all other API
                                                      LambdaList
 They enrich the Java Collection          add()

 Framework API with a fluent
 interface that allows to use the                  java.util.List
 lambdaj's features
                                                   aggregate()
 Invoking the methods of this fluent      sort()                   retain()
 interface also change the state of         group()
                                                       convert()
                                                                   clone()
 the original wrapped collection
 The instance of the wrapped collection doesn’t change so its
 characteristics are always reflected even by the wrapping
 lambdaj counterpart
 If you need to leave the original collection unchanged clone it:
      with(sales).clone().remove(…) …
Let’s go functional


    Closures
                            j
(actually lambda expressions)
lambdaj's closure
Closures (or more properly lambda expressions) can
be defined through the usual lambdaj DSL style
   Closure println = closure(); {
      of(System.out).println(var(String.class));
                                                    j
   }


and then invoked by "closing" its free variable once:
   println.apply("one");


or more times:
   println.each("one", "two", "three");
Closure’s features
   Typed closure
                                                                     j
Closure2<Integer,Integer> adder = closure(Integer.class, Integer.class); {

}
   of(this).sum(var(Integer.class), var(Integer.class));



   Curry
Closure1<Integer> adderOf10 = adder.curry2(10);


   Mix variables and fixed values
Closure1<Integer> adderOf10 = closure(Integer.class); {
   of(this).sum(var(Integer.class), 10);
}


   Cast a closure to a one-method interface (SAM)
Converter<Integer,Integer> converter = adderOf10.cast(Converter.class);
Closure’s features (2)
   Keep unbound the object on which the closure is invoked


   }
       of(Person.class).setAge(var(Integer.class));

   Define a closure without using a ThreadLocal
                                                                      j
Closure2<Person, Integer> ageSetter = closure(Person.class, Integer.class); {




Closure2<Person, Integer> ageSetter = new Closure2<Person, Integer>() {{
       of(Person.class).setAge(var(Integer.class));
   }};
   Define the invocation of a static method …
Closure1<String> intParser = closure(String.class)
        .of(Integer.class, "parseInt", var(String.class));
   … or of a constructor
Closure2<String, Integer> personCreator = closure()
       .of(Person.class, CONSTRUCTOR, var(String.class), var(Integer.class));
Switcher
public List<String> sortStrings(List<String> list) {

}
       // a sort algorithm suitable for Strings

public List<T> sortSmallList(List<T> list) {

}
       // a sort algorithm suitable for no more than 100 items
                                                                        j
public List<String> sort(List<String> list) {
       // a generic sort algorithm
}



Switcher<List<T>> sortStrategy = new Switcher<List<T>>()
   .addCase(having(on(List.class).get(0), instanceOf(String.class))),
        new Closure() {{ of(this).sortStrings(var(List.class)); }})
   .addCase(having(on(List.class).size(), lessThan(100))),
        new Closure() {{ of(this).sortSmallList(var(List.class)); }})
   .setDefault(new Closure() {{ of(this).sort(var(List.class)); }});
Check out lambdaj at:
http://lambdaj.googlecode.com

             Thank you

Mario Fusco
mario.fusco@gmail.com
twitter: @mariofusco
1 of 31

No more loops with lambdaj

Download to read offline
Mario Fusco
Mario FuscoDrools project lead at Red Hat

Recommended

Monadic Java by
Monadic JavaMonadic Java
Monadic JavaCodemotion
1.2K views52 slides
Monadic Java by
Monadic JavaMonadic Java
Monadic JavaMario Fusco
65.9K views73 slides
Unlocking the Magic of Monads with Java 8 by
Unlocking the Magic of Monads with Java 8Unlocking the Magic of Monads with Java 8
Unlocking the Magic of Monads with Java 8JavaDayUA
938 views72 slides
Map(), flatmap() and reduce() are your new best friends: simpler collections,... by
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Chris Richardson
38.4K views94 slides
Javaz. Functional design in Java 8. by
Javaz. Functional design in Java 8.Javaz. Functional design in Java 8.
Javaz. Functional design in Java 8.Vadim Dubs
2.4K views53 slides
Let's make a contract: the art of designing a Java API by
Let's make a contract: the art of designing a Java APILet's make a contract: the art of designing a Java API
Let's make a contract: the art of designing a Java APIMario Fusco
2.7K views92 slides
From object oriented to functional domain modeling by
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modelingMario Fusco
15.3K views60 slides
Pragmatic functional refactoring with java 8 by
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8RichardWarburton
4.3K views54 slides

More Related Content

What's hot

Game of Life - Polyglot FP - Haskell, Scala, Unison - Part 2 - with minor cor... by
Game of Life - Polyglot FP - Haskell, Scala, Unison - Part 2 - with minor cor...Game of Life - Polyglot FP - Haskell, Scala, Unison - Part 2 - with minor cor...
Game of Life - Polyglot FP - Haskell, Scala, Unison - Part 2 - with minor cor...Philip Schwarz
443 views55 slides
Laziness, trampolines, monoids and other functional amenities: this is not yo... by
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Mario Fusco
7.1K views46 slides
Type Classes in Scala and Haskell by
Type Classes in Scala and HaskellType Classes in Scala and Haskell
Type Classes in Scala and HaskellHermann Hueck
1.4K views61 slides
Java 8 Workshop by
Java 8 WorkshopJava 8 Workshop
Java 8 WorkshopMario Fusco
7.4K views85 slides
FP in Java - Project Lambda and beyond by
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondMario Fusco
18.4K views39 slides
OOP and FP - Become a Better Programmer by
OOP and FP - Become a Better ProgrammerOOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerMario Fusco
6.1K views44 slides
Functional programming by
Functional programmingFunctional programming
Functional programmingChristian Hujer
1.2K views133 slides
Introduction to Functional Programming in JavaScript by
Introduction to Functional Programming in JavaScriptIntroduction to Functional Programming in JavaScript
Introduction to Functional Programming in JavaScripttmont
9.1K views44 slides
Functional Programming Patterns (BuildStuff '14) by
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Scott Wlaschin
175.3K views249 slides
Jumping-with-java8 by
Jumping-with-java8Jumping-with-java8
Jumping-with-java8Dhaval Dalal
6.4K views175 slides
Learning Functional Programming Without Growing a Neckbeard by
Learning Functional Programming Without Growing a NeckbeardLearning Functional Programming Without Growing a Neckbeard
Learning Functional Programming Without Growing a NeckbeardKelsey Gilmore-Innis
25.3K views65 slides
If You Think You Can Stay Away from Functional Programming, You Are Wrong by
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongMario Fusco
7.4K views44 slides
Functional Programming in JavaScript by Luis Atencio by
Functional Programming in JavaScript by Luis AtencioFunctional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis AtencioLuis Atencio
7.2K views64 slides
DIWE - Advanced PHP Concepts by
DIWE - Advanced PHP ConceptsDIWE - Advanced PHP Concepts
DIWE - Advanced PHP ConceptsRasan Samarasinghe
1.3K views81 slides
Pragmatic functional refactoring with java 8 (1) by
Pragmatic functional refactoring with java 8 (1)Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)RichardWarburton
3.7K views66 slides
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM by
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMMario Fusco
5K views29 slides
Intro to Functional Programming by
Intro to Functional ProgrammingIntro to Functional Programming
Intro to Functional ProgrammingHugo Firth
4.9K views65 slides
Java 7, 8 & 9 - Moving the language forward by
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardMario Fusco
4.3K views13 slides
Introduction to ad-3.4, an automatic differentiation library in Haskell by
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskellnebuta
905 views21 slides
Introduction to Monads in Scala (1) by
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)stasimus
10.2K views45 slides

What's hot (20)

Game of Life - Polyglot FP - Haskell, Scala, Unison - Part 2 - with minor cor... by Philip Schwarz
Game of Life - Polyglot FP - Haskell, Scala, Unison - Part 2 - with minor cor...Game of Life - Polyglot FP - Haskell, Scala, Unison - Part 2 - with minor cor...
Game of Life - Polyglot FP - Haskell, Scala, Unison - Part 2 - with minor cor...
Philip Schwarz443 views
Laziness, trampolines, monoids and other functional amenities: this is not yo... by Mario Fusco
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Mario Fusco7.1K views
Type Classes in Scala and Haskell by Hermann Hueck
Type Classes in Scala and HaskellType Classes in Scala and Haskell
Type Classes in Scala and Haskell
Hermann Hueck1.4K views
Java 8 Workshop by Mario Fusco
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
Mario Fusco7.4K views
FP in Java - Project Lambda and beyond by Mario Fusco
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
Mario Fusco18.4K views
OOP and FP - Become a Better Programmer by Mario Fusco
OOP and FP - Become a Better ProgrammerOOP and FP - Become a Better Programmer
OOP and FP - Become a Better Programmer
Mario Fusco6.1K views
Introduction to Functional Programming in JavaScript by tmont
Introduction to Functional Programming in JavaScriptIntroduction to Functional Programming in JavaScript
Introduction to Functional Programming in JavaScript
tmont9.1K views
Functional Programming Patterns (BuildStuff '14) by Scott Wlaschin
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
Scott Wlaschin175.3K views
Jumping-with-java8 by Dhaval Dalal
Jumping-with-java8Jumping-with-java8
Jumping-with-java8
Dhaval Dalal6.4K views
Learning Functional Programming Without Growing a Neckbeard by Kelsey Gilmore-Innis
Learning Functional Programming Without Growing a NeckbeardLearning Functional Programming Without Growing a Neckbeard
Learning Functional Programming Without Growing a Neckbeard
Kelsey Gilmore-Innis25.3K views
If You Think You Can Stay Away from Functional Programming, You Are Wrong by Mario Fusco
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are Wrong
Mario Fusco7.4K views
Functional Programming in JavaScript by Luis Atencio by Luis Atencio
Functional Programming in JavaScript by Luis AtencioFunctional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis Atencio
Luis Atencio7.2K views
Pragmatic functional refactoring with java 8 (1) by RichardWarburton
Pragmatic functional refactoring with java 8 (1)Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)
RichardWarburton3.7K views
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM by Mario Fusco
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Mario Fusco5K views
Intro to Functional Programming by Hugo Firth
Intro to Functional ProgrammingIntro to Functional Programming
Intro to Functional Programming
Hugo Firth4.9K views
Java 7, 8 & 9 - Moving the language forward by Mario Fusco
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
Mario Fusco4.3K views
Introduction to ad-3.4, an automatic differentiation library in Haskell by nebuta
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
nebuta905 views
Introduction to Monads in Scala (1) by stasimus
Introduction to Monads in Scala (1)Introduction to Monads in Scala (1)
Introduction to Monads in Scala (1)
stasimus10.2K views

Similar to No more loops with lambdaj

PorfolioReport by
PorfolioReportPorfolioReport
PorfolioReportAlbert Chu
181 views4 slides
Streams and lambdas the good, the bad and the ugly by
Streams and lambdas the good, the bad and the uglyStreams and lambdas the good, the bad and the ugly
Streams and lambdas the good, the bad and the uglyPeter Lawrey
3.2K views20 slides
JDD2014: Real life lambdas - Peter Lawrey by
JDD2014: Real life lambdas - Peter LawreyJDD2014: Real life lambdas - Peter Lawrey
JDD2014: Real life lambdas - Peter LawreyPROIDEA
361 views20 slides
MongoDB World 2018: Keynote by
MongoDB World 2018: KeynoteMongoDB World 2018: Keynote
MongoDB World 2018: KeynoteMongoDB
1.5K views126 slides
w3schools.com THE WORLDS LARGEST WEB DEVELOPER SITE by
w3schools.com  THE WORLDS LARGEST WEB DEVELOPER SITE w3schools.com  THE WORLDS LARGEST WEB DEVELOPER SITE
w3schools.com THE WORLDS LARGEST WEB DEVELOPER SITE tidwellerin392
3 views34 slides
DSL - expressive syntax on top of a clean semantic model by
DSL - expressive syntax on top of a clean semantic modelDSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic modelDebasish Ghosh
3.4K views83 slides
Reactive Access to MongoDB from Scala by
Reactive Access to MongoDB from ScalaReactive Access to MongoDB from Scala
Reactive Access to MongoDB from ScalaHermann Hueck
3.1K views61 slides
Practical scalaz by
Practical scalazPractical scalaz
Practical scalazoxbow_lakes
4.6K views41 slides
Creating an Uber Clone - Part XXVII - Transcript.pdf by
Creating an Uber Clone - Part XXVII - Transcript.pdfCreating an Uber Clone - Part XXVII - Transcript.pdf
Creating an Uber Clone - Part XXVII - Transcript.pdfShaiAlmog1
261 views10 slides
Functional programming in Javascript by
Functional programming in JavascriptFunctional programming in Javascript
Functional programming in JavascriptKnoldus Inc.
1.8K views15 slides
Functional programming techniques in real-world microservices by
Functional programming techniques in real-world microservicesFunctional programming techniques in real-world microservices
Functional programming techniques in real-world microservicesAndrás Papp
355 views75 slides
XKE Typeclass by
XKE TypeclassXKE Typeclass
XKE TypeclassMathieu DULAC
180 views43 slides
Joy of scala by
Joy of scalaJoy of scala
Joy of scalaMaxim Novak
13.3K views99 slides
20.1 Java working with abstraction by
20.1 Java working with abstraction20.1 Java working with abstraction
20.1 Java working with abstractionIntro C# Book
8.2K views47 slides
Legacy lambda code by
Legacy lambda codeLegacy lambda code
Legacy lambda codePeter Lawrey
1.5K views35 slides
Django 1.1 Tour by
Django 1.1 TourDjango 1.1 Tour
Django 1.1 TourIdan Gazit
904 views58 slides
12. Basic SQL Queries (2).pptx by
12. Basic SQL Queries  (2).pptx12. Basic SQL Queries  (2).pptx
12. Basic SQL Queries (2).pptxSabrinaShanta2
7 views39 slides
Say Goodbye to Procedural Programming - Nick Sutterer by
Say Goodbye to Procedural Programming - Nick SuttererSay Goodbye to Procedural Programming - Nick Sutterer
Say Goodbye to Procedural Programming - Nick SuttererRuby Meditation
380 views178 slides
Refactoring to Macros with Clojure by
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
3.5K views51 slides
G*ワークショップ in 仙台 Grails(とことん)入門 by
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門Tsuyoshi Yamamoto
1.6K views84 slides

Similar to No more loops with lambdaj (20)

PorfolioReport by Albert Chu
PorfolioReportPorfolioReport
PorfolioReport
Albert Chu181 views
Streams and lambdas the good, the bad and the ugly by Peter Lawrey
Streams and lambdas the good, the bad and the uglyStreams and lambdas the good, the bad and the ugly
Streams and lambdas the good, the bad and the ugly
Peter Lawrey3.2K views
JDD2014: Real life lambdas - Peter Lawrey by PROIDEA
JDD2014: Real life lambdas - Peter LawreyJDD2014: Real life lambdas - Peter Lawrey
JDD2014: Real life lambdas - Peter Lawrey
PROIDEA361 views
MongoDB World 2018: Keynote by MongoDB
MongoDB World 2018: KeynoteMongoDB World 2018: Keynote
MongoDB World 2018: Keynote
MongoDB1.5K views
w3schools.com THE WORLDS LARGEST WEB DEVELOPER SITE by tidwellerin392
w3schools.com  THE WORLDS LARGEST WEB DEVELOPER SITE w3schools.com  THE WORLDS LARGEST WEB DEVELOPER SITE
w3schools.com THE WORLDS LARGEST WEB DEVELOPER SITE
tidwellerin3923 views
DSL - expressive syntax on top of a clean semantic model by Debasish Ghosh
DSL - expressive syntax on top of a clean semantic modelDSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic model
Debasish Ghosh3.4K views
Reactive Access to MongoDB from Scala by Hermann Hueck
Reactive Access to MongoDB from ScalaReactive Access to MongoDB from Scala
Reactive Access to MongoDB from Scala
Hermann Hueck3.1K views
Practical scalaz by oxbow_lakes
Practical scalazPractical scalaz
Practical scalaz
oxbow_lakes4.6K views
Creating an Uber Clone - Part XXVII - Transcript.pdf by ShaiAlmog1
Creating an Uber Clone - Part XXVII - Transcript.pdfCreating an Uber Clone - Part XXVII - Transcript.pdf
Creating an Uber Clone - Part XXVII - Transcript.pdf
ShaiAlmog1261 views
Functional programming in Javascript by Knoldus Inc.
Functional programming in JavascriptFunctional programming in Javascript
Functional programming in Javascript
Knoldus Inc.1.8K views
Functional programming techniques in real-world microservices by András Papp
Functional programming techniques in real-world microservicesFunctional programming techniques in real-world microservices
Functional programming techniques in real-world microservices
András Papp355 views
Joy of scala by Maxim Novak
Joy of scalaJoy of scala
Joy of scala
Maxim Novak13.3K views
20.1 Java working with abstraction by Intro C# Book
20.1 Java working with abstraction20.1 Java working with abstraction
20.1 Java working with abstraction
Intro C# Book8.2K views
Legacy lambda code by Peter Lawrey
Legacy lambda codeLegacy lambda code
Legacy lambda code
Peter Lawrey1.5K views
Django 1.1 Tour by Idan Gazit
Django 1.1 TourDjango 1.1 Tour
Django 1.1 Tour
Idan Gazit904 views
Say Goodbye to Procedural Programming - Nick Sutterer by Ruby Meditation
Say Goodbye to Procedural Programming - Nick SuttererSay Goodbye to Procedural Programming - Nick Sutterer
Say Goodbye to Procedural Programming - Nick Sutterer
Ruby Meditation380 views
Refactoring to Macros with Clojure by Dmitry Buzdin
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin3.5K views
G*ワークショップ in 仙台 Grails(とことん)入門 by Tsuyoshi Yamamoto
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門
Tsuyoshi Yamamoto1.6K views

More from Mario Fusco

Kogito: cloud native business automation by
Kogito: cloud native business automationKogito: cloud native business automation
Kogito: cloud native business automationMario Fusco
903 views78 slides
How and why I turned my old Java projects into a first-class serverless compo... by
How and why I turned my old Java projects into a first-class serverless compo...How and why I turned my old Java projects into a first-class serverless compo...
How and why I turned my old Java projects into a first-class serverless compo...Mario Fusco
1.8K views39 slides
OOP and FP by
OOP and FPOOP and FP
OOP and FPMario Fusco
4K views77 slides
Lazy java by
Lazy javaLazy java
Lazy javaMario Fusco
6.3K views66 slides
Drools 6 deep dive by
Drools 6 deep diveDrools 6 deep dive
Drools 6 deep diveMario Fusco
8.6K views50 slides
Reactive Programming for a demanding world: building event-driven and respons... by
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Mario Fusco
7.7K views32 slides
Comparing different concurrency models on the JVM by
Comparing different concurrency models on the JVMComparing different concurrency models on the JVM
Comparing different concurrency models on the JVMMario Fusco
10.2K views49 slides
Why we cannot ignore Functional Programming by
Why we cannot ignore Functional ProgrammingWhy we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingMario Fusco
3.1K views30 slides
Real world DSL - making technical and business people speaking the same language by
Real world DSL - making technical and business people speaking the same languageReal world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same languageMario Fusco
10.8K views26 slides
Introducing Drools by
Introducing DroolsIntroducing Drools
Introducing DroolsMario Fusco
8.2K views28 slides
Hammurabi by
HammurabiHammurabi
HammurabiMario Fusco
3.3K views25 slides
Swiss army knife Spring by
Swiss army knife SpringSwiss army knife Spring
Swiss army knife SpringMario Fusco
1.7K views24 slides
Scala - where objects and functions meet by
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meetMario Fusco
1.8K views32 slides

More from Mario Fusco (13)

Kogito: cloud native business automation by Mario Fusco
Kogito: cloud native business automationKogito: cloud native business automation
Kogito: cloud native business automation
Mario Fusco903 views
How and why I turned my old Java projects into a first-class serverless compo... by Mario Fusco
How and why I turned my old Java projects into a first-class serverless compo...How and why I turned my old Java projects into a first-class serverless compo...
How and why I turned my old Java projects into a first-class serverless compo...
Mario Fusco1.8K views
Drools 6 deep dive by Mario Fusco
Drools 6 deep diveDrools 6 deep dive
Drools 6 deep dive
Mario Fusco8.6K views
Reactive Programming for a demanding world: building event-driven and respons... by Mario Fusco
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
Mario Fusco7.7K views
Comparing different concurrency models on the JVM by Mario Fusco
Comparing different concurrency models on the JVMComparing different concurrency models on the JVM
Comparing different concurrency models on the JVM
Mario Fusco10.2K views
Why we cannot ignore Functional Programming by Mario Fusco
Why we cannot ignore Functional ProgrammingWhy we cannot ignore Functional Programming
Why we cannot ignore Functional Programming
Mario Fusco3.1K views
Real world DSL - making technical and business people speaking the same language by Mario Fusco
Real world DSL - making technical and business people speaking the same languageReal world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same language
Mario Fusco10.8K views
Introducing Drools by Mario Fusco
Introducing DroolsIntroducing Drools
Introducing Drools
Mario Fusco8.2K views
Swiss army knife Spring by Mario Fusco
Swiss army knife SpringSwiss army knife Spring
Swiss army knife Spring
Mario Fusco1.7K views
Scala - where objects and functions meet by Mario Fusco
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
Mario Fusco1.8K views

Recently uploaded

The Big Book of Venture Capital - 2023 by
The Big Book of Venture Capital - 2023The Big Book of Venture Capital - 2023
The Big Book of Venture Capital - 2023Rohit Yadav
3.7K views203 slides
Transcript: Show and tell: What’s in your tech stack? - Tech Forum 2023 by
Transcript: Show and tell: What’s in your tech stack? - Tech Forum 2023Transcript: Show and tell: What’s in your tech stack? - Tech Forum 2023
Transcript: Show and tell: What’s in your tech stack? - Tech Forum 2023BookNet Canada
44 views16 slides
The Free Energy Secrets of Cold Electricity by
The Free Energy Secrets of Cold ElectricityThe Free Energy Secrets of Cold Electricity
The Free Energy Secrets of Cold ElectricityNOMADPOWER
12 views156 slides
Optimizing Communication to Optimize Human Behavior - LCBM by
Optimizing Communication to Optimize Human Behavior - LCBMOptimizing Communication to Optimize Human Behavior - LCBM
Optimizing Communication to Optimize Human Behavior - LCBMYaman Kumar
65 views49 slides
Choosing the Right Flutter App Development Company by
Choosing the Right Flutter App Development CompanyChoosing the Right Flutter App Development Company
Choosing the Right Flutter App Development CompanyFicode Technologies
19 views9 slides
Network eWaste : Community role to manage end of life Product by
Network eWaste : Community role to manage end of life ProductNetwork eWaste : Community role to manage end of life Product
Network eWaste : Community role to manage end of life ProductBangladesh Network Operators Group
26 views13 slides
[2024] GDSC India - Discover, Design, Develop.pdf.pdf by
[2024] GDSC India - Discover, Design, Develop.pdf.pdf[2024] GDSC India - Discover, Design, Develop.pdf.pdf
[2024] GDSC India - Discover, Design, Develop.pdf.pdfbcedsc
32 views19 slides
Bronack Skills - Risk Management and SRE v1.0 12-10-2023.pdf by
Bronack Skills - Risk Management and SRE v1.0 12-10-2023.pdfBronack Skills - Risk Management and SRE v1.0 12-10-2023.pdf
Bronack Skills - Risk Management and SRE v1.0 12-10-2023.pdfThomasBronack
52 views32 slides
2024 Solution Challenge - Presentation Template.pdf by
2024 Solution Challenge - Presentation Template.pdf2024 Solution Challenge - Presentation Template.pdf
2024 Solution Challenge - Presentation Template.pdfAbhinavNautiyal8
18 views24 slides
What is Authentication Active Directory_.pptx by
What is Authentication Active Directory_.pptxWhat is Authentication Active Directory_.pptx
What is Authentication Active Directory_.pptxHeenaMehta35
34 views7 slides
The Power of Generative AI in Accelerating No Code Adoption.pdf by
The Power of Generative AI in Accelerating No Code Adoption.pdfThe Power of Generative AI in Accelerating No Code Adoption.pdf
The Power of Generative AI in Accelerating No Code Adoption.pdfSaeed Al Dhaheri
67 views18 slides
Taking Off with FME: Elevating Airport Operations to New Heights by
Taking Off with FME: Elevating Airport Operations to New HeightsTaking Off with FME: Elevating Airport Operations to New Heights
Taking Off with FME: Elevating Airport Operations to New HeightsSafe Software
105 views61 slides
3D Internet Seminar Report.pdf by
3D Internet Seminar Report.pdf3D Internet Seminar Report.pdf
3D Internet Seminar Report.pdfroshnimp27
12 views29 slides
Everything You Always Wanted to Know About AsyncAPI by
Everything You Always Wanted to Know About AsyncAPIEverything You Always Wanted to Know About AsyncAPI
Everything You Always Wanted to Know About AsyncAPIPostman
21 views25 slides
Large Language Models, Data & APIs - Integrating Generative AI Power into you... by
Large Language Models, Data & APIs - Integrating Generative AI Power into you...Large Language Models, Data & APIs - Integrating Generative AI Power into you...
Large Language Models, Data & APIs - Integrating Generative AI Power into you...NETUserGroupBern
24 views33 slides
Building a Strong Data Governance Framework for DevOps | Software Development... by
Building a Strong Data Governance Framework for DevOps | Software Development...Building a Strong Data Governance Framework for DevOps | Software Development...
Building a Strong Data Governance Framework for DevOps | Software Development...Dieter Ziegler
27 views7 slides
2023 Ivanti December Patch Tuesday by
2023 Ivanti December Patch Tuesday2023 Ivanti December Patch Tuesday
2023 Ivanti December Patch TuesdayIvanti
18 views34 slides
Xavier M Culmination Presenetation Final 12-7.pptx by
Xavier M Culmination Presenetation Final 12-7.pptxXavier M Culmination Presenetation Final 12-7.pptx
Xavier M Culmination Presenetation Final 12-7.pptxmanzanaresxavier28
45 views10 slides
Discover Aura Workshop (12.5.23).pdf by
Discover Aura Workshop (12.5.23).pdfDiscover Aura Workshop (12.5.23).pdf
Discover Aura Workshop (12.5.23).pdfNeo4j
30 views55 slides
Introduction to UiPath Testing and learning how to build Test Cases by
Introduction to UiPath Testing and learning how to build Test CasesIntroduction to UiPath Testing and learning how to build Test Cases
Introduction to UiPath Testing and learning how to build Test CasesDianaGray10
22 views11 slides

Recently uploaded (20)

The Big Book of Venture Capital - 2023 by Rohit Yadav
The Big Book of Venture Capital - 2023The Big Book of Venture Capital - 2023
The Big Book of Venture Capital - 2023
Rohit Yadav3.7K views
Transcript: Show and tell: What’s in your tech stack? - Tech Forum 2023 by BookNet Canada
Transcript: Show and tell: What’s in your tech stack? - Tech Forum 2023Transcript: Show and tell: What’s in your tech stack? - Tech Forum 2023
Transcript: Show and tell: What’s in your tech stack? - Tech Forum 2023
BookNet Canada44 views
The Free Energy Secrets of Cold Electricity by NOMADPOWER
The Free Energy Secrets of Cold ElectricityThe Free Energy Secrets of Cold Electricity
The Free Energy Secrets of Cold Electricity
NOMADPOWER12 views
Optimizing Communication to Optimize Human Behavior - LCBM by Yaman Kumar
Optimizing Communication to Optimize Human Behavior - LCBMOptimizing Communication to Optimize Human Behavior - LCBM
Optimizing Communication to Optimize Human Behavior - LCBM
Yaman Kumar65 views
[2024] GDSC India - Discover, Design, Develop.pdf.pdf by bcedsc
[2024] GDSC India - Discover, Design, Develop.pdf.pdf[2024] GDSC India - Discover, Design, Develop.pdf.pdf
[2024] GDSC India - Discover, Design, Develop.pdf.pdf
bcedsc32 views
Bronack Skills - Risk Management and SRE v1.0 12-10-2023.pdf by ThomasBronack
Bronack Skills - Risk Management and SRE v1.0 12-10-2023.pdfBronack Skills - Risk Management and SRE v1.0 12-10-2023.pdf
Bronack Skills - Risk Management and SRE v1.0 12-10-2023.pdf
ThomasBronack52 views
2024 Solution Challenge - Presentation Template.pdf by AbhinavNautiyal8
2024 Solution Challenge - Presentation Template.pdf2024 Solution Challenge - Presentation Template.pdf
2024 Solution Challenge - Presentation Template.pdf
AbhinavNautiyal818 views
What is Authentication Active Directory_.pptx by HeenaMehta35
What is Authentication Active Directory_.pptxWhat is Authentication Active Directory_.pptx
What is Authentication Active Directory_.pptx
HeenaMehta3534 views
The Power of Generative AI in Accelerating No Code Adoption.pdf by Saeed Al Dhaheri
The Power of Generative AI in Accelerating No Code Adoption.pdfThe Power of Generative AI in Accelerating No Code Adoption.pdf
The Power of Generative AI in Accelerating No Code Adoption.pdf
Saeed Al Dhaheri67 views
Taking Off with FME: Elevating Airport Operations to New Heights by Safe Software
Taking Off with FME: Elevating Airport Operations to New HeightsTaking Off with FME: Elevating Airport Operations to New Heights
Taking Off with FME: Elevating Airport Operations to New Heights
Safe Software105 views
3D Internet Seminar Report.pdf by roshnimp27
3D Internet Seminar Report.pdf3D Internet Seminar Report.pdf
3D Internet Seminar Report.pdf
roshnimp2712 views
Everything You Always Wanted to Know About AsyncAPI by Postman
Everything You Always Wanted to Know About AsyncAPIEverything You Always Wanted to Know About AsyncAPI
Everything You Always Wanted to Know About AsyncAPI
Postman21 views
Large Language Models, Data & APIs - Integrating Generative AI Power into you... by NETUserGroupBern
Large Language Models, Data & APIs - Integrating Generative AI Power into you...Large Language Models, Data & APIs - Integrating Generative AI Power into you...
Large Language Models, Data & APIs - Integrating Generative AI Power into you...
NETUserGroupBern24 views
Building a Strong Data Governance Framework for DevOps | Software Development... by Dieter Ziegler
Building a Strong Data Governance Framework for DevOps | Software Development...Building a Strong Data Governance Framework for DevOps | Software Development...
Building a Strong Data Governance Framework for DevOps | Software Development...
Dieter Ziegler27 views
2023 Ivanti December Patch Tuesday by Ivanti
2023 Ivanti December Patch Tuesday2023 Ivanti December Patch Tuesday
2023 Ivanti December Patch Tuesday
Ivanti18 views
Xavier M Culmination Presenetation Final 12-7.pptx by manzanaresxavier28
Xavier M Culmination Presenetation Final 12-7.pptxXavier M Culmination Presenetation Final 12-7.pptx
Xavier M Culmination Presenetation Final 12-7.pptx
Discover Aura Workshop (12.5.23).pdf by Neo4j
Discover Aura Workshop (12.5.23).pdfDiscover Aura Workshop (12.5.23).pdf
Discover Aura Workshop (12.5.23).pdf
Neo4j30 views
Introduction to UiPath Testing and learning how to build Test Cases by DianaGray10
Introduction to UiPath Testing and learning how to build Test CasesIntroduction to UiPath Testing and learning how to build Test Cases
Introduction to UiPath Testing and learning how to build Test Cases
DianaGray1022 views

No more loops with lambdaj

  • 1. No more loops with λambdaj An internal DSL to manipulate collections without loops by Mario Fusco mario.fusco@gmail.com twitter: @mariofusco
  • 2. Why is lambdaj born? The best way to understand what lambdaj does and how it works is to start asking why we felt the need to develop it: We were on a project with a complex data model j The biggest part of our business logic did almost always the same: iterating over collections of our business objects in order to do the same set of tasks Loops (especially when nested or mixed with conditions) are harder to be read than to be written We wanted to write our business logic in a less technical and closer to business fashion
  • 3. What is lambdaj for? It provides a DSL to manipulate collections in a pseudo-functional and statically typed way. It eliminates the burden to write (often poorly readable) loops while iterating over collections. j It allows to iterate collections in order to: convert aggregate filter index group sort extract
  • 4. How does lambdaj work? lambdaj is a thread safe library of static methods based on 2 main features: treating a collection as it was a single object by allowing to propagate a single method invocation j to all the objects in the collection forEach(personsInFamily).setLastName("Fusco"); allowing to define a reference to a java method in a statically typed way sort(persons, on(Person.class).getAge());
  • 6. Print all cars’ brands Iterative version: StringBuilder sb = new StringBuilder(); j for (Car car : cars) sb.append(car.getBrand()).append(", "); String brands = sb.toString().substring(0, sb.length()-2); lambdaj version: String brands = joinFrom(cars).getBrand();
  • 7. Select all sales of a Ferrari Iterative version: List<Sale> salesOfAFerrari = new ArrayList<Sale>(); for (Sale sale : sales) { if (sale.getCar().getBrand().equals("Ferrari")) j salesOfAFerrari.add(sale); } lambdaj version: List<Sale> salesOfAFerrari = select(sales, having(on(Sale.class).getCar().getBrand(),equalTo("Ferrari")));
  • 8. Find buys of youngest person Iterative version: Person youngest = null; for (Person person : persons) j if (youngest == null || person.getAge() < youngest.getAge()) youngest = person; List<Sale> buys = new ArrayList<Sale>(); for (Sale sale : sales) if (sale.getBuyer().equals(youngest)) buys.add(sale); lambdaj version: List<Sale> sales = select(sales,having(on(Sale.class).getBuyer(), equalTo(selectMin(persons, on(Person.class).getAge()))));
  • 9. Find most costly sale Iterative version: double maxCost = 0.0; j for (Sale sale : sales) { double cost = sale.getCost(); if (cost > maxCost) maxCost = cost; } lambdaj version: Sol. 1 -> double maxCost = max(sales, on(Sale.class).getCost()); Sol. 2 -> double maxCost = maxFrom(sales).getCost();
  • 10. Sum costs where both are males Iterative version: double sum = 0.0; for (Sale sale : sales) { j if (sale.getBuyer().isMale() && sale.getSeller().isMale()) sum += sale.getCost(); } lambdaj version: double sum = sumFrom(select(sales, having(on(Sale.class).getBuyer().isMale()).and( having(on(Sale.class).getSeller().isMale())))).getCost();
  • 11. Find age of youngest who bought for more than 50,000 Iterative version: int age = Integer.MAX_VALUE; j for (Sale sale : sales) { if (sale.getCost() > 50000.00) { int buyerAge = sale.getBuyer().getAge(); if (buyerAge < age) age = buyerAge; } } lambdaj version: int age = min(forEach(select(sales, having(on(Sale.class).getCost(), greaterThan(50000.00)))) .getBuyer(), on(Person.class).getAge());
  • 12. Sort sales by cost Iterative version: List<Sale> sortedSales = new ArrayList<Sale>(sales); Collections.sort(sortedSales, new Comparator<Sale>() { j public int compare(Sale s1, Sale s2) { return Double.valueOf(s1.getCost()).compareTo(s2.getCost()); } }); lambdaj version: List<Sale> sortedSales = sort(sales, on(Sale.class).getCost());
  • 13. Extract cars’ original cost Iterative version: List<Double> costs = new ArrayList<Double>(); for (Car car : cars) j costs.add(car.getOriginalValue()); lambdaj version: List<Double> costs = extract(cars, on(Car.class).getOriginalValue());
  • 14. Index cars by brand Iterative version: Map<String, Car> carsByBrand = new HashMap<String, Car>(); for (Car car : cars) j carsByBrand.put(car.getBrand(), car); lambdaj version: Map<String, Car> carsByBrand = index(cars, on(Car.class).getBrand());
  • 15. Group sales by buyers and sellers (iterative version) Person buyer = sale.getBuyer(); Map<Person, Sale> buyerMap = map.get(buyer); if (buyerMap == null) { buyerMap = new HashMap<Person, Sale>(); j Map<Person,Map<Person,Sale>> map = new HashMap<Person,Map<Person,Sale>>(); for (Sale sale : sales) { map.put(buyer, buyerMap); } buyerMap.put(sale.getSeller(), sale); } Person youngest = null; Person oldest = null; for (Person person : persons) { if (youngest == null || person.getAge() < youngest.getAge()) youngest = person; if (oldest == null || person.getAge() > oldest.getAge()) oldest = person; } Sale saleFromYoungestToOldest = map.get(youngest).get(oldest);
  • 16. Group sales by buyers and sellers (lambdaj version) Group<Sale> group = group(sales, j by(on(Sale.class).getBuyer()),by(on(Sale.class).getSeller())); Person youngest = selectMin(persons, on(Person.class).getAge()); Person oldest = selectMax(persons, on(Person.class).getAge()); Sale sale = group.findGroup(youngest).findGroup(oldest).first();
  • 17. Find most bought car (iterative version) Map<Car, Integer> carsBought = new HashMap<Car, Integer>(); for (Sale sale : sales) { Car car = sale.getCar(); Integer boughtTimes = carsBought.get(car); j carsBought.put(car, boughtTimes == null ? 1 : boughtTimes+1); } Car mostBoughtCarIterative = null; int boughtTimesIterative = 0; for (Entry<Car, Integer> entry : carsBought.entrySet()) { if (entry.getValue() > boughtTimesIterative) { mostBoughtCarIterative = entry.getKey(); boughtTimesIterative = entry.getValue(); } }
  • 18. Find most bought car (lambdaj version) Group<Sale> group = selectMax( group(sales, by(on(Sale.class).getCar())).subgroups(), on(Group.class).getSize()); Car mostBoughtCar = group.first().getCar(); j int boughtTimes = group.getSize();
  • 19. How does lambdaj work? The getCar() invocation is propagated by the first proxy to all the sales. The cars returned by these invocations are put again in a list and another proxy, similar to the first one, is created to wrap this list, allowing to repeat this type of invocation once more (proxy concatenation). j Car fastestCar = max( forEach(sales).getCar(), A proxy wraps the on(Car.class).getSpeed()); list of sales. The returned object is of class Sale but A proxy of the Car class is created in dynamically order to register the invocations on it. implements the These invocations will be then Iterable interface too reapplied to the cars of the former list
  • 20. Lambdaj’s extensibility List<Double> speeds = extract(cars, on(Car.class).getSpeed()); is the short form for: j List<Double> speeds = convert(cars, new Car2SpeedConverter()); where the Car2SpeedConverter is defined as: class Car2SpeedConverter implements Converter<Car, Double> { public Double convert(Car car) { return car.getSpeed(); } }
  • 21. Performance analysis Minimum, maximum and average duration in milliseconds of 20 runs with 100,000 iterations of the former examples iterative lambdaj min max avg min max avg ratio PrintAllBrands 265 312 283 1,310 1,591 1,377 4.866 FindAllSalesOfAFerrari 281 437 366 1,528 1,607 1,566 4.279 FindAllBuysOfYoungestPerson 5,585 5,975 5,938 6,895 6,989 6,936 1.168 FindMostCostlySaleValue 218 234 227 655 702 670 2.952 SumCostsWhereBothActorsAreAMale 358 452 375 2,199 2,637 2,247 5.992 AgeOfYoungestBuyerForMoreThan50K 5,257 5,319 5,292 9,625 9,750 9,696 1.832 SortSalesByCost 1,388 1,482 1,448 3,213 3,245 3,231 2.231 ExtractCarsOriginalCost 140 156 141 234 249 236 1.674 IndexCarsByBrand 172 203 186 327 343 336 1.806 GroupSalesByBuyersAndSellers 9,469 9,766 9,507 12,698 12,838 12,753 1.341 FindMostBoughtCar 3,744 3,884 3,846 4,181 4,259 4211 1.095 Average ratio = 2.658
  • 22. Known limitations Lack of reified generics lambdaj cannot infer the actual type to be returned when a null or empty collection is passed to forEach() List<Person> persons = new ArrayList<Person>(); j forEach(persons).setLastName("Fusco"); Exception Impossibility to proxy a final class the on() construct cannot register an invocation after a final Class is met List<Person> sortedByNamePersons = sort(persons, on(Person.class).getName().toLowerCase()); Exception
  • 23. Let’s write it fluently Fluent j Interface Collections
  • 24. Why Fluent Interfaces List<Person> richBuyersSortedByAge = sort( extract( select(sales, having(on(Sale.class).getValue(), greaterThan(50000))) j ), on(Sale.class).getBuyer() ), on(Person.class).getAge()); List<Person> richBuyersSortedByAge = with(sales) .retain(having(on(Sale.class).getValue(),greaterThan(50000))) .extract(on(Sale.class).getBuyer()) .sort(on(Person.class).getAge());
  • 25. LambdaCollections LambdaCollections implement the java.util.List corresponding Java interface (i.e. add() implements LambdaList is a java.util.List) so you can use them in all other API LambdaList They enrich the Java Collection add() Framework API with a fluent interface that allows to use the java.util.List lambdaj's features aggregate() Invoking the methods of this fluent sort() retain() interface also change the state of group() convert() clone() the original wrapped collection The instance of the wrapped collection doesn’t change so its characteristics are always reflected even by the wrapping lambdaj counterpart If you need to leave the original collection unchanged clone it: with(sales).clone().remove(…) …
  • 26. Let’s go functional Closures j (actually lambda expressions)
  • 27. lambdaj's closure Closures (or more properly lambda expressions) can be defined through the usual lambdaj DSL style Closure println = closure(); { of(System.out).println(var(String.class)); j } and then invoked by "closing" its free variable once: println.apply("one"); or more times: println.each("one", "two", "three");
  • 28. Closure’s features Typed closure j Closure2<Integer,Integer> adder = closure(Integer.class, Integer.class); { } of(this).sum(var(Integer.class), var(Integer.class)); Curry Closure1<Integer> adderOf10 = adder.curry2(10); Mix variables and fixed values Closure1<Integer> adderOf10 = closure(Integer.class); { of(this).sum(var(Integer.class), 10); } Cast a closure to a one-method interface (SAM) Converter<Integer,Integer> converter = adderOf10.cast(Converter.class);
  • 29. Closure’s features (2) Keep unbound the object on which the closure is invoked } of(Person.class).setAge(var(Integer.class)); Define a closure without using a ThreadLocal j Closure2<Person, Integer> ageSetter = closure(Person.class, Integer.class); { Closure2<Person, Integer> ageSetter = new Closure2<Person, Integer>() {{ of(Person.class).setAge(var(Integer.class)); }}; Define the invocation of a static method … Closure1<String> intParser = closure(String.class) .of(Integer.class, "parseInt", var(String.class)); … or of a constructor Closure2<String, Integer> personCreator = closure() .of(Person.class, CONSTRUCTOR, var(String.class), var(Integer.class));
  • 30. Switcher public List<String> sortStrings(List<String> list) { } // a sort algorithm suitable for Strings public List<T> sortSmallList(List<T> list) { } // a sort algorithm suitable for no more than 100 items j public List<String> sort(List<String> list) { // a generic sort algorithm } Switcher<List<T>> sortStrategy = new Switcher<List<T>>() .addCase(having(on(List.class).get(0), instanceOf(String.class))), new Closure() {{ of(this).sortStrings(var(List.class)); }}) .addCase(having(on(List.class).size(), lessThan(100))), new Closure() {{ of(this).sortSmallList(var(List.class)); }}) .setDefault(new Closure() {{ of(this).sort(var(List.class)); }});
  • 31. Check out lambdaj at: http://lambdaj.googlecode.com Thank you Mario Fusco mario.fusco@gmail.com twitter: @mariofusco