SlideShare uma empresa Scribd logo
1 de 80
Baixar para ler offline
1   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Jump-Starting Lambda
Stuart Marks                                                         @stuartmarks
Mike Duigou                                                          @mjduigou

Oracle JDK Core Libraries Team


2   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
What is Lambda?


           Essentially an anonymous function
                    –  allows one to treat code as data
                    –  provides parameterization of behavior as opposed to values or types
                    –  provides “closures” (but we’re not exploring closure properties here)
           Combined with JVM and class library changes, supports
                    –  high productivity, flexible, “fluent” style of programming
                    –  explicit but unobtrusive parallelism
                    –  useful for simple, everyday programming
                    –  also heavy (parallel) lifting

3   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Presentation Overview


           Exploring programming techniques leading toward Lambda
           Little emphasis on syntax and
            language definition
           Examples driven by use cases
           Illustrate lambda’s
            usefulness for simple,
            everyday programming
            tasks


4   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Example Overview


           Person object
           Using a collection of Person objects (e.g. a List)
           Selecting some of these Person objects
                    –  e.g., by age or sex
           Operations using Person objects
                    –  e.g., making an automated phone call (“robocall”)




5   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Canonical Example Object

         class Person {
             int getAge();
             Sex getSex();
             PhoneNumber getPhoneNumber();
             EmailAddr getEmailAddr();
             PostalAddr getPostalAddr();
             /* ... */
         }




6   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Robocall Every Person

         void robocallEveryPerson() {
             List<Person> list = gatherPersons();
             for (Person p : list) {
                 PhoneNumber num = p.getPhoneNumber();
                 robocall(num);
             }
         }




7   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Some Use Cases


           Select only eligible drivers
                    –  in California, must be 16 years or older
           Select only eligible voters
                    –  in the U.S., must be 18 years or older
           Select only persons of legal drinking age
                    –  in California, must be 21 years or older




8   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Robocall Eligible Drivers

         void robocallEligibleDrivers() {
             List<Person> list = gatherPersons();
             for (Person p : list) {
                 if (p.getAge() >= 16) {
                     PhoneNumber num = p.getPhoneNumber();
                     robocall(num);
                 }
             }
         }




9   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Robocall Eligible Voters

          void robocallEligibleVoters() {
              List<Person> list = gatherPersons();
              for (Person p : list) {
                  if (p.getAge() >= 18) {
                      PhoneNumber num = p.getPhoneNumber();
                      robocall(num);
                  }
              }
          }




10   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Robocall Persons of Legal Drinking Age

          void robocallLegalDrinkers() {
              List<Person> list = gatherPersons();
              for (Person p : list) {
                  if (p.getAge() >= 21) {
                      PhoneNumber num = p.getPhoneNumber();
                      robocall(num);
                  }
              }
          }




11   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Duplicated code!
                                                                            Notice a pattern?



12   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Solution: Add a Parameter!

          void robocallPersonsOlderThan(int age) {
              List<Person> list = gatherPersons();
              for (Person p : list) {
                  if (p.getAge() >= age) {
                      PhoneNumber num = p.getPhoneNumber();
                      robocall(num);
                  }
              }
          }




13   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Using Parameters

          void robocallDrivers() {
              robocallPersonsOlderThan(16);
          }

          void robocallVoters() {
              robocallPersonsOlderThan(18);
          }

          void robocallDrinkers() {
              robocallPersonsOlderThan(21);
          }


14   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Additional Use Case


            Commercial pilots have mandatory retirement age of 65
            Previously we parameterized a value
            Now, we want to parameterize less-than or greater-than
                     –  Add a boolean?




15   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Boolean Parameter Encodes Less-or-Greater

          void robocallPersonsWithAgeLimit(int age, boolean lessThan)
          {
              List<Person> list = gatherPersons();
              for (Person p : list) {
                  if ( lessThan && (p.getAge() < age) ||
                      !lessThan && (p.getAge() >= age)) {
                      PhoneNumber num = p.getPhoneNumber();
                      robocall(num);
                  }
              }
          }


16   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Using the Boolean Parameter

          void robocallEligibleDrivers()
              { robocallPersonsWithAgeLimit(16, false); }

          void robocallEligibleVoters()
              { robocallPersonsWithAgeLimit(18, false); }

          void robocallLegalDrinkers()
              { robocallPersonsWithAgeLimit(21, false); }

          void robocallEligiblePilots()
              { robocallPersonsWithAgeLimit(65, true); }


17   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Let’s face it, this sucks




18   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Corrected Use Case


            Commercial pilots also have a minimum age of 23
                     –  as well as a mandatory retirement age of 65
            Use an age range instead...




19   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Parameters for Age Range

          void robocallPersonsInAgeRange(int low, int high) {
              List<Person> list = gatherPersons();
              for (Person p : list) {
                  if (low <= p.getAge() && p.getAge() < high) {
                      PhoneNumber num = p.getPhoneNumber();
                      robocall(num);
                  }
              }
          }




20   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Using Age Range
                                                                            Integer.MAX_VALUE

          void robocallEligibleDrivers()
              { robocallPersonsInAgeRange(16, MAX); }

          void robocallEligibleVoters()
              { robocallPersonsInAgeRange(18, MAX); }

          void robocallLegalDrinkers()
              { robocallPersonsInAgeRange(21, MAX); }

          void robocallEligiblePilots()
              { robocallPersonsInAgeRange(23, 65);                           }


21   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Additional Use Case


            United States Selective Service (national service program)
                     –  Age range 18 to 25 (inclusive)


                                                      void robocallSelectiveService() {
                                                          robocallPersonsInAgeRange(18, 26);
                                                      }




22   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Corrected Use Case


            United States Selective Service                                enum Sex { MALE, FEMALE }
                     –  Age range 18 to 25 (inclusive), men only
            Change to:
                                  void robocallSelectiveService() {
                                      robocallPersonsInAgeRange(18, 26, MALE);
                                  }
            Works, but what about queries that don’t care about sex?
                     –  Add DONT_CARE to enum Sex? Mixes data with query value.
                     –  Use null? (Yes, enums can be null; weird special case.)


23   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Parameterized Computation


            Value parameterization is useful, but only to a certain point
                     –  Problem: meta-information is communicated “in-band”
                     –  In these cases we need a value that means “don’t care”
                     –  Sometimes special values can be found that work:
                                    0, -1, Integer.MAX_VALUE, null
                     –  If not, add more boolean, enum parameters
            Just age and sex, but already we sort of need a query language
            A giant leap: parameterize behavior instead of values
                     –  Make a method’s parameter be a function instead of a value

24   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Functions: Parameters and Return Values


          (int, int) ➞ int                                                  example: addition


          String ➞ int                                                      example: length


          Person ➞ boolean                                                  example: several, let’s revisit


25   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Examples of Person → boolean Functions

          boolean checkIfPersonIsEligibleToDrive(Person p) {
              return p.getAge() >= 16;
          }

          boolean checkIfPersonIsEligibleToVote(Person p) {
              return p.getAge() >= 18;
          }

          boolean checkIfPersonIsLegalToDrink(Person p) {
              return p.getAge() >= 21;
          }


26   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Examples of Person → boolean Functions

          boolean checkIfPersonIsEligiblePilot(Person p) {
              return p.getAge >= 23 && p.getAge() < 65;
          }

          boolean checkIfPersonEligibleForSelectiveService(Person p)
          {
              return p.getSex() == MALE &&
                     p.getAge() >= 18 &&
                     p.getAge() <= 25;
          }




27   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
How To Pass a Function in Java?

             Use anonymous inner classes:

          new Thread(
              new Runnable() {
                  public void run() {
                      System.out.println("I'm another thread!");
                  }
              }
          ).start();




28   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
What is the Type of a Function in Java?

          ( ) ➞ void


          interface Runnable {                                              This is a functional interface —
              public void run();                                            an interface with a single method *
          }
                                                                                       * To be precise, we should say single
                                                                                       abstract method, since in Java 8 it is
            empty argument list                                                        now possible for interfaces to have
                                                                                       implementations via the default method
                                                                                       feature.




29   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Predicate: Function Returning Boolean

          Person ➞ boolean


          interface PersonPredicate {
              boolean testPerson(Person p);
          }




30   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
A Generalized Predicate

          T ➞ boolean


          interface Predicate<T> {
              boolean test(T t);
          }




31   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Using a Function Passed as a Parameter

          void robocallMatchingPersons(Predicate<Person> pred) {
              List<Person> list = gatherPersons();
              for (Person p : list) {
                  if (pred.test(p)) {
                      PhoneNumber num = p.getPhoneNumber();
                      robocall(num);
                  }
              }
          }




32   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Passing a Function as a Parameter

          void robocallEligibleDrivers() {
              robocallMatchingPersons(
                  new Predicate<Person>() {
                      public boolean test(Person p) {
                          return p.getAge() >= 16;
                      }
                  });
          }




33   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Passing a Function as a Parameter

          void robocallEligibleVoters() {
              robocallMatchingPersons(
                  new Predicate<Person>() {
                      public boolean test(Person p) {
                          return p.getAge() >= 18;
                      }
                  });
          }




34   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Passing a Function as a Parameter

          void robocallLegalDrinkers()   {
              robocallMatchingPersons(
                  new Predicate<Person>() {
                      public boolean test(Person p) {
                          return p.getAge() >= 21;
                      }
                  });
          }




35   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Passing a Function as a Parameter

          void robocallEligiblePilots() {
              robocallMatchingPersons(
                  new Predicate<Person>() {
                      public boolean test(Person p) {
                          return p.getAge() >= 23 &&
                                 p.getAge() < 65;
                      }
                  });
          }




36   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Passing a Function as a Parameter

          void robocallSelectiveServiceCandidates() {
              robocallMatchingPersons(
                  new Predicate<Person>() {
                      public boolean test(Person p) {
                          return p.getSex() == MALE &&
                                 p.getAge() >= 18 &&
                                 p.getAge() <= 25;
                      }
                  });
          }




37   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Powerful, but verbose, and
                                                 very, very painful



38   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
The Significant Part

          void robocallEligibleDrivers() {
              robocallMatchingPersons(
                  new Predicate<Person>() {
                      public boolean test(Person p) {
                          return p.getAge() >= 16;
                      }
                  });
          }




39   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
The Boilerplate

          void robocallEligibleDrivers() {
              robocallMatchingPersons(
                  new Predicate<Person>() {
                      public boolean test(Person p) {
                          return p.getAge() >= 16;
                      }
                  });
          }




40   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Erase the Boilerplate

          void robocallEligibleDrivers() {
              robocallMatchingPersons(

                                                                                               p
                                                                            -> p.getAge() >= 16

                                                 );
          }




41   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Our First Lambda Expression!

          void robocallEligibleDrivers() {
              robocallMatchingPersons(p -> p.getAge() >= 16);
          }
                                                                                      body

                                                      parameters
                                                                                    Lambda expressions
                                                                                    are converted to
                                                                            arrow   instances of
                                                                                    functional interfaces


42   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Our First Lambda Expression!

          void robocallEligibleDrivers() {
              robocallMatchingPersons(p -> p.getAge() >= 16);
          }

                                                              Type Inference:      Person ➞ boolean

                                                                                boolean test(Person)

                                                                                     Target Type

         void robocallMatchingPersons(Predicate<Person> pred) {
             ...
         }
43   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Rewrites Using Lambda

          void robocallEligibleDrivers() {
              robocallMatchingPersons(p -> p.getAge() >= 16);
          }

          void robocallEligibleVoters() {
              robocallMatchingPersons(p -> p.getAge() >= 18);
          }

          void robocallLegalDrinkers()   {
              robocallMatchingPersons(p -> p.getAge() >= 21);
          }


44   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Rewrites Using Lambda

          void robocallEligiblePilots() {
              robocallMatchingPersons(
                  p -> p.getAge() >= 23 && p.getAge() < 65);
          }

          void robocallSelectiveServiceCandidates() {
              robocallMatchingPersons(p -> p.getSex() == MALE &&
                                           p.getAge() >= 18 &&
                                           p.getAge() <= 25);
          }




45   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Where Else Can We Use Lambda?

          void robocallMatchingPersons(Predicate<Person> pred) {
              List<Person> list = gatherPersons();
              for (Person p : list) {
                  if (pred.test(p)) {
                      PhoneNumber num = p.getPhoneNumber();
                      robocall(num);
                  }
              }
          }




46   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Where Else Can We Use Lambda?

          void txtmsgMatchingPersons(Predicate<Person> pred) {
              List<Person> list = gatherPersons();
              for (Person p : list) {
                  if (pred.test(p)) {
                      PhoneNumber num = p.getPhoneNumber();
                      txtmsg(num);
                  }
              }
          }




47   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Functional Interface: Block

          PhoneNumber ➞ void


          T ➞ void

          interface Block<T> {
              void apply(T t);
          }




48   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Extract & Parameterize Block Function

          void processMatchingPersons(Predicate<Person> pred,
                                      Block<PhoneNumber> block) {
              List<Person> list = gatherPersons();
              for (Person p : list) {
                  if (pred.test(p)) {
                      PhoneNumber num = p.getPhoneNumber();
                      block.apply(num);
                  }
              }
          }




49   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Examples of Block

          processMatchingPersons(p -> p.getAge() >= 16,
                                 num -> { robocall(num); });


          processMatchingPersons(p -> p.getAge() >= 18,
                                 num -> { txtmsg(num); });


                                                                            These are “statement lambdas” as
                                                                            opposed to “expression lambdas”



50   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
What Else Can We Extract?

          void processMatchingPersons(Predicate<Person> pred,
                                      Block<PhoneNumber> block) {
              List<Person> list = gatherPersons();
              for (Person p : list) {
                  if (pred.test(p)) {
                      PhoneNumber num = p.getPhoneNumber();
                      block.apply(num);
                  }
              }
          }




51   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Functional Interface: Mapper

          Person ➞ PhoneNumber


          T➞U

          interface Mapper<T,U> {
              U map(T t);
          }



52   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Extract & Parameterize Mapper Function

          void processMatchingPersons(Predicate<Person> pred,
                                   Mapper<Person,PhoneNumber> mapper,
                                   Block<PhoneNumber> block)
          {
              List<Person> list = gatherPersons();
              for (Person p : list) {
                  if (pred.test(p)) {
                      PhoneNumber num = mapper.map(p);
                      block.apply(num);
                  }
              }
          }

53   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Examples of Mapper

          processMatchingPersons(p -> p.getAge() >= 16,
                                 p -> p.getHomePhoneNumber(),
                                 num -> { robocall(num); });

          processMatchingPersons(p -> p.getAge() >= 18,
                                 p -> p.getMobilePhoneNumber(),
                                 num -> { txtmsg(num); });




54   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Refactoring & Cleanup

          void processMatchingPersons(Predicate<Person> pred,
                                   Mapper<Person,PhoneNumber> mapper,
                                   Block<PhoneNumber> block)
          {
              List<Person> list = gatherPersons();
              for (Person p : list) {
                  if (pred.test(p)) {
                      PhoneNumber num = mapper.map(p);
                      block.apply(num);
                  }
              }
          }

55   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Refactoring & Cleanup

          void processMatchingPersons(List<Person> list,
                                   Predicate<Person> pred,
                                   Mapper<Person,PhoneNumber> mapper,
                                   Block<PhoneNumber> block)
          {
              for (Person p : list) {
                  if (pred.test(p)) {
                      PhoneNumber num = mapper.map(p);
                      block.apply(num);
                  }
              }
          }

56   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Refactoring & Cleanup

          void processMatchingPersons(Iterable<Person> source,
                                   Predicate<Person> pred,
                                   Mapper<Person,PhoneNumber> mapper,
                                   Block<PhoneNumber> block)
          {
              for (Person p : source) {
                  if (pred.test(p)) {
                      PhoneNumber num = mapper.map(p);
                      block.apply(num);
                  }
              }
          }

57   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Usage After Refactoring

          // robocall eligible drivers
          processMatchingPersons(gatherPersons(),
                                 p -> p.getAge() >= 16,
                                 p -> p.getHomePhoneNumber(),
                                 num -> { robocall(num); });

          // text-message eligible voters
          processMatchingPersons(gatherPersons(),
                                 p -> p.getAge() >= 18,
                                 p -> p.getMobilePhoneNumber(),
                                 num -> { txtmsg(num); });


58   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
What Does processMatchingPersons Really Do?

          void processMatchingPersons(Iterable<Person> source,
                                   Predicate<Person> pred,
                                   Mapper<Person,PhoneNumber> mapper,
                                   Block<PhoneNumber> block)
          {
              for (Person p : source) {
                  if (pred.test(p)) {
                      PhoneNumber num = mapper.map(p);
                      block.apply(num);
                  }
              }
          }

59   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
What Does processMatchingPersons Really Do?




                            << source provides Person objects >> {
                                << filter each Person through a predicate >> {
                                    << map each Person to a PhoneNumber >>
                                    << apply a function to each PhoneNumber >>
                                }
                            }


60   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
A General Form of processMatchingPersons




                            << source provides elements >> {
                                << filter each through a predicate >> {
                                    << map each value to another value >>
                                    << apply a function to each value >>
                                }
                            }


61   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
A General Form of processMatchingPersons




                                                                            lambda    lambda   lambda


                             Source                                          Filter   Mapper    Apply




62   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
OK great, but can we really
                                               write the code this way?



63   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Building a Pipeline for Robocalling

          void robocallEligibleDrivers() {
              gatherPersons()




64   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Building a Pipeline for Robocalling

          void robocallEligibleDrivers() {
              gatherPersons().stream()
                  .filter(...)
                  .map(...)
                  .forEach(...);
          }




                             Source                                         Filter   Mapper   Apply




65   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Building a Pipeline

          void robocallEligibleDrivers() {
              gatherPersons().stream()
                  .filter(p -> p.getAge() >= 16)
                  .map(p -> p.getHomePhoneNumber())
                  .forEach(num -> { robocall(num); });
          }

                                                                            lambda    lambda   lambda


                             Source                                          Filter   Mapper    Apply




66   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Changing the Pipeline

          void robocallEligibleDrivers() {
              gatherPersons().stream()
                  .filter(p -> p.getAge() >= 16)
                  .map(p -> p.getHomePhoneNumber())
                  .filter(num -> !num.isOnDoNotCallList())
                  .forEach(num -> { robocall(num); });
          }




67   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Changing the Pipeline

          void textMessageEligibleDrivers() {
              gatherPersons().stream()
                  .filter(p -> p.getAge() >= 16)
                  .map(p -> p.getMobilePhoneNumber())
                  .filter(num -> !num.isOnDoNotCallList())
                  .forEach(num -> { txtmsg(num); });
          }




68   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Changing the Pipeline

          void spamEligibleDrinkers() {
              gatherPersons().stream()
                  .filter(p -> p.getAge() >= 21)
                  .map(p -> p.getEmailAddr())
                  .forEach(addr -> { sendEmail(addr); });
          }




69   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Changing the Pipeline

          void bulkMailEligiblePilots() {
              gatherPersons().stream()
                  .filter(p -> p.getAge() >= 23 && p.getAge() < 65)
                  .map(p -> p.getPostalAddr())
                  .forEach(addr -> { sendBulkMail(addr); });
          }




70   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Changing the Pipeline

          void recruitSelectiveServiceCandidates() {
              gatherPersons().stream()
                  .filter(p -> p.getSex() == MALE &&
                          p.getAge() >= 18 &&
                          p.getAge() <= 25)
                  .map(p -> p.getHomeAddr())
                  .forEach(addr -> { sendArmyRecruiter(addr); });
          }




71   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
How To Do Stuff in Parallel?

          void robocallEligibleDrivers() {
              gatherPersons().parallel()
                             .stream()
                  .filter(p -> p.getAge() >= 16)
                  .map(p -> p.getHomePhoneNumber())
                  .forEach(num -> { robocall(num); });
          }




72   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Functional Interfaces in java.util.functions


          BinaryOperator<T>                                                 (T, T) ➞ T
          Block<T>                                                          T ➞ void
          Combiner<T,U,V>                                                   (T, U) ➞ V
          Factory<T>                                                        () ➞ T
          FlatMapper<T,R>                                                   T ➞ R*
          Mapper<T,U>                                                       T➞U
          Predicate<T>                                                      T ➞ boolean
          UnaryOperator<T>                                                  T➞T

73   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Stream Operations
         java.util.stream.Stream


            filter(pred)                                                     toArray(array-factory)
            map(mapper)                                                      any / all / noneMatch(pred)
            forEach(block)                                                   findFirst / Any(pred)
            flatMap(flat-mapper)                                             cumulate(binop)
            tee(block)                                                       reduce(binop) / reduce(base, binop)
            uniqueElements()                                                 fold(base-factory, reducer, combiner)
            sorted(comparator)                                               groupBy(mapper)
            into(collection)                                                 reduceBy(mapper, base-factory, reducer)

74   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Summary


            Lambdas are anonymous functions
                     –  They enable parameterization of behavior
            Lambda expressions are converted to functional interfaces
                     –  A functional interface is an interface with a single (abstract) method
            Two kinds: expression lambdas and statement lambdas
            Compiler type inference reduces boilerplate
            Lambda + new library APIs enable writing programs that are:
                     –  powerful, fluid, expressive, parallel


75   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Related Talks – All Brian Goetz, All The Time


            The Road To Lambda (earlier J1 talk)
            Lambda: A Peek Under the Hood (earlier J1 talk)
            Implementing Lambda Expressions in Java
                     –  JVM Language Summit 2012
                     –  http://www.oracle.com/technetwork/java/
                            javase/community/jvmls2012-1840099.html            λ
            Language / Library / VM Co-evolution in
                Java SE 8, Devoxx 2011
                     –  https://blogs.oracle.com/briangoetz/entry/slides_from_devoxx_talk_on

76   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Links


            Lambda project page:
                     http://openjdk.java.net/projects/lambda/
            Source code:
                     http://hg.openjdk.java.net/lambda/lambda
            Binaries:
                     http://jdk8.java.net/lambda/                           λ
            FAQ (Maurice Naftalin):
                     http://www.lambdafaq.org/


77   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Any Questions?




78   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
The preceding is intended to outline our general product direction. It is intended
         for information purposes only, and may not be incorporated into any contract.
         It is not a commitment to deliver any material, code, or functionality, and should
         not be relied upon in making purchasing decisions. The development, release,
         and timing of any features or functionality described for Oracle s products
         remains at the sole discretion of Oracle.




79   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Graphic Section Divider




80   Copyright © 2012, Oracle and/or its affiliates. All rights reserved.

Mais conteúdo relacionado

Semelhante a Lambda Expressions

What’s New in Oracle Database 12c for PHP
What’s New in Oracle Database 12c for PHPWhat’s New in Oracle Database 12c for PHP
What’s New in Oracle Database 12c for PHPChristopher Jones
 
Project Helidon Overview (Japanese)
Project Helidon Overview (Japanese)Project Helidon Overview (Japanese)
Project Helidon Overview (Japanese)Logico
 
Java EE 7 Platform: Boosting Productivity and Embracing HTML5 - Arun Gupta (R...
Java EE 7 Platform: Boosting Productivity and Embracing HTML5 - Arun Gupta (R...Java EE 7 Platform: Boosting Productivity and Embracing HTML5 - Arun Gupta (R...
Java EE 7 Platform: Boosting Productivity and Embracing HTML5 - Arun Gupta (R...jaxLondonConference
 
Java EE 7: Boosting Productivity and Embracing HTML5
Java EE 7: Boosting Productivity and Embracing HTML5Java EE 7: Boosting Productivity and Embracing HTML5
Java EE 7: Boosting Productivity and Embracing HTML5Arun Gupta
 
What's new for JavaFX in JDK8 - Weaver
What's new for JavaFX in JDK8 - WeaverWhat's new for JavaFX in JDK8 - Weaver
What's new for JavaFX in JDK8 - WeaverCodemotion
 
Java EE 8 - What’s new on the Web front
Java EE 8 - What’s new on the Web frontJava EE 8 - What’s new on the Web front
Java EE 8 - What’s new on the Web frontDavid Delabassee
 
Latin America Tour 2019 - 18c and 19c featues
Latin America Tour 2019   - 18c and 19c featuesLatin America Tour 2019   - 18c and 19c featues
Latin America Tour 2019 - 18c and 19c featuesConnor McDonald
 
JAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX London
JAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX LondonJAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX London
JAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX LondonArun Gupta
 
Graal and Truffle: One VM to Rule Them All
Graal and Truffle: One VM to Rule Them AllGraal and Truffle: One VM to Rule Them All
Graal and Truffle: One VM to Rule Them AllThomas Wuerthinger
 
Keeping Up with Java: Look at All These New Features!
Keeping Up with Java: Look at All These New Features!Keeping Up with Java: Look at All These New Features!
Keeping Up with Java: Look at All These New Features!VMware Tanzu
 
Batch Applications for the Java Platform
Batch Applications for the Java PlatformBatch Applications for the Java Platform
Batch Applications for the Java PlatformSivakumar Thyagarajan
 
18c and 19c features for DBAs
18c and 19c features for DBAs18c and 19c features for DBAs
18c and 19c features for DBAsConnor McDonald
 
A Importância do JavaFX no Mercado Embedded
A Importância do JavaFX no Mercado EmbeddedA Importância do JavaFX no Mercado Embedded
A Importância do JavaFX no Mercado EmbeddedBruno Borges
 
Intro to GraphQL for Database Developers
Intro to GraphQL for Database DevelopersIntro to GraphQL for Database Developers
Intro to GraphQL for Database DevelopersDaniel McGhan
 
Towards JVM Dynamic Languages Toolchain
Towards JVM Dynamic Languages ToolchainTowards JVM Dynamic Languages Toolchain
Towards JVM Dynamic Languages ToolchainAttila Szegedi
 
Melbourne Groundbreakers Tour - Upgrading without risk
Melbourne Groundbreakers Tour - Upgrading without riskMelbourne Groundbreakers Tour - Upgrading without risk
Melbourne Groundbreakers Tour - Upgrading without riskConnor McDonald
 
Sangam 18 - The New Optimizer in Oracle 12c
Sangam 18 - The New Optimizer in Oracle 12cSangam 18 - The New Optimizer in Oracle 12c
Sangam 18 - The New Optimizer in Oracle 12cConnor McDonald
 
Ruby on Rails Oracle adaptera izstrāde
Ruby on Rails Oracle adaptera izstrādeRuby on Rails Oracle adaptera izstrāde
Ruby on Rails Oracle adaptera izstrādeRaimonds Simanovskis
 

Semelhante a Lambda Expressions (20)

What’s New in Oracle Database 12c for PHP
What’s New in Oracle Database 12c for PHPWhat’s New in Oracle Database 12c for PHP
What’s New in Oracle Database 12c for PHP
 
Project Helidon Overview (Japanese)
Project Helidon Overview (Japanese)Project Helidon Overview (Japanese)
Project Helidon Overview (Japanese)
 
Java EE 7 Platform: Boosting Productivity and Embracing HTML5 - Arun Gupta (R...
Java EE 7 Platform: Boosting Productivity and Embracing HTML5 - Arun Gupta (R...Java EE 7 Platform: Boosting Productivity and Embracing HTML5 - Arun Gupta (R...
Java EE 7 Platform: Boosting Productivity and Embracing HTML5 - Arun Gupta (R...
 
Java EE 7: Boosting Productivity and Embracing HTML5
Java EE 7: Boosting Productivity and Embracing HTML5Java EE 7: Boosting Productivity and Embracing HTML5
Java EE 7: Boosting Productivity and Embracing HTML5
 
What's new for JavaFX in JDK8 - Weaver
What's new for JavaFX in JDK8 - WeaverWhat's new for JavaFX in JDK8 - Weaver
What's new for JavaFX in JDK8 - Weaver
 
Kotlin
KotlinKotlin
Kotlin
 
Java EE 7 overview
Java EE 7 overviewJava EE 7 overview
Java EE 7 overview
 
Java EE 8 - What’s new on the Web front
Java EE 8 - What’s new on the Web frontJava EE 8 - What’s new on the Web front
Java EE 8 - What’s new on the Web front
 
Latin America Tour 2019 - 18c and 19c featues
Latin America Tour 2019   - 18c and 19c featuesLatin America Tour 2019   - 18c and 19c featues
Latin America Tour 2019 - 18c and 19c featues
 
JAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX London
JAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX LondonJAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX London
JAX-RS 2.0: New and Noteworthy in RESTful Web services API at JAX London
 
Graal and Truffle: One VM to Rule Them All
Graal and Truffle: One VM to Rule Them AllGraal and Truffle: One VM to Rule Them All
Graal and Truffle: One VM to Rule Them All
 
Keeping Up with Java: Look at All These New Features!
Keeping Up with Java: Look at All These New Features!Keeping Up with Java: Look at All These New Features!
Keeping Up with Java: Look at All These New Features!
 
Batch Applications for the Java Platform
Batch Applications for the Java PlatformBatch Applications for the Java Platform
Batch Applications for the Java Platform
 
18c and 19c features for DBAs
18c and 19c features for DBAs18c and 19c features for DBAs
18c and 19c features for DBAs
 
A Importância do JavaFX no Mercado Embedded
A Importância do JavaFX no Mercado EmbeddedA Importância do JavaFX no Mercado Embedded
A Importância do JavaFX no Mercado Embedded
 
Intro to GraphQL for Database Developers
Intro to GraphQL for Database DevelopersIntro to GraphQL for Database Developers
Intro to GraphQL for Database Developers
 
Towards JVM Dynamic Languages Toolchain
Towards JVM Dynamic Languages ToolchainTowards JVM Dynamic Languages Toolchain
Towards JVM Dynamic Languages Toolchain
 
Melbourne Groundbreakers Tour - Upgrading without risk
Melbourne Groundbreakers Tour - Upgrading without riskMelbourne Groundbreakers Tour - Upgrading without risk
Melbourne Groundbreakers Tour - Upgrading without risk
 
Sangam 18 - The New Optimizer in Oracle 12c
Sangam 18 - The New Optimizer in Oracle 12cSangam 18 - The New Optimizer in Oracle 12c
Sangam 18 - The New Optimizer in Oracle 12c
 
Ruby on Rails Oracle adaptera izstrāde
Ruby on Rails Oracle adaptera izstrādeRuby on Rails Oracle adaptera izstrāde
Ruby on Rails Oracle adaptera izstrāde
 

Mais de Vinay H G

Continuous integration using jenkins
Continuous integration using jenkinsContinuous integration using jenkins
Continuous integration using jenkinsVinay H G
 
Developers best practices_tutorial
Developers best practices_tutorialDevelopers best practices_tutorial
Developers best practices_tutorialVinay H G
 
Javamagazine20140304 dl
Javamagazine20140304 dlJavamagazine20140304 dl
Javamagazine20140304 dlVinay H G
 
Hibernate tutorial
Hibernate tutorialHibernate tutorial
Hibernate tutorialVinay H G
 
Java 8 selected updates
Java 8 selected updatesJava 8 selected updates
Java 8 selected updatesVinay H G
 
Why should i switch to Java SE 7
Why should i switch to Java SE 7Why should i switch to Java SE 7
Why should i switch to Java SE 7Vinay H G
 
Javase7 1641812
Javase7 1641812Javase7 1641812
Javase7 1641812Vinay H G
 
Tutorial storybook
Tutorial storybookTutorial storybook
Tutorial storybookVinay H G
 
Virtual dev-day-java7-keynote-1641807
Virtual dev-day-java7-keynote-1641807Virtual dev-day-java7-keynote-1641807
Virtual dev-day-java7-keynote-1641807Vinay H G
 
Agile practice-2012
Agile practice-2012Agile practice-2012
Agile practice-2012Vinay H G
 
OAuth with Restful Web Services
OAuth with Restful Web Services OAuth with Restful Web Services
OAuth with Restful Web Services Vinay H G
 
Java Garbage Collection
Java Garbage CollectionJava Garbage Collection
Java Garbage CollectionVinay H G
 

Mais de Vinay H G (12)

Continuous integration using jenkins
Continuous integration using jenkinsContinuous integration using jenkins
Continuous integration using jenkins
 
Developers best practices_tutorial
Developers best practices_tutorialDevelopers best practices_tutorial
Developers best practices_tutorial
 
Javamagazine20140304 dl
Javamagazine20140304 dlJavamagazine20140304 dl
Javamagazine20140304 dl
 
Hibernate tutorial
Hibernate tutorialHibernate tutorial
Hibernate tutorial
 
Java 8 selected updates
Java 8 selected updatesJava 8 selected updates
Java 8 selected updates
 
Why should i switch to Java SE 7
Why should i switch to Java SE 7Why should i switch to Java SE 7
Why should i switch to Java SE 7
 
Javase7 1641812
Javase7 1641812Javase7 1641812
Javase7 1641812
 
Tutorial storybook
Tutorial storybookTutorial storybook
Tutorial storybook
 
Virtual dev-day-java7-keynote-1641807
Virtual dev-day-java7-keynote-1641807Virtual dev-day-java7-keynote-1641807
Virtual dev-day-java7-keynote-1641807
 
Agile practice-2012
Agile practice-2012Agile practice-2012
Agile practice-2012
 
OAuth with Restful Web Services
OAuth with Restful Web Services OAuth with Restful Web Services
OAuth with Restful Web Services
 
Java Garbage Collection
Java Garbage CollectionJava Garbage Collection
Java Garbage Collection
 

Lambda Expressions

  • 1. 1 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 2. Jump-Starting Lambda Stuart Marks @stuartmarks Mike Duigou @mjduigou Oracle JDK Core Libraries Team 2 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 3. What is Lambda?   Essentially an anonymous function –  allows one to treat code as data –  provides parameterization of behavior as opposed to values or types –  provides “closures” (but we’re not exploring closure properties here)   Combined with JVM and class library changes, supports –  high productivity, flexible, “fluent” style of programming –  explicit but unobtrusive parallelism –  useful for simple, everyday programming –  also heavy (parallel) lifting 3 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 4. Presentation Overview   Exploring programming techniques leading toward Lambda   Little emphasis on syntax and language definition   Examples driven by use cases   Illustrate lambda’s usefulness for simple, everyday programming tasks 4 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 5. Example Overview   Person object   Using a collection of Person objects (e.g. a List)   Selecting some of these Person objects –  e.g., by age or sex   Operations using Person objects –  e.g., making an automated phone call (“robocall”) 5 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 6. Canonical Example Object class Person { int getAge(); Sex getSex(); PhoneNumber getPhoneNumber(); EmailAddr getEmailAddr(); PostalAddr getPostalAddr(); /* ... */ } 6 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 7. Robocall Every Person void robocallEveryPerson() { List<Person> list = gatherPersons(); for (Person p : list) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } 7 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 8. Some Use Cases   Select only eligible drivers –  in California, must be 16 years or older   Select only eligible voters –  in the U.S., must be 18 years or older   Select only persons of legal drinking age –  in California, must be 21 years or older 8 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 9. Robocall Eligible Drivers void robocallEligibleDrivers() { List<Person> list = gatherPersons(); for (Person p : list) { if (p.getAge() >= 16) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } } 9 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 10. Robocall Eligible Voters void robocallEligibleVoters() { List<Person> list = gatherPersons(); for (Person p : list) { if (p.getAge() >= 18) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } } 10 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 11. Robocall Persons of Legal Drinking Age void robocallLegalDrinkers() { List<Person> list = gatherPersons(); for (Person p : list) { if (p.getAge() >= 21) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } } 11 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 12. Duplicated code! Notice a pattern? 12 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 13. Solution: Add a Parameter! void robocallPersonsOlderThan(int age) { List<Person> list = gatherPersons(); for (Person p : list) { if (p.getAge() >= age) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } } 13 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 14. Using Parameters void robocallDrivers() { robocallPersonsOlderThan(16); } void robocallVoters() { robocallPersonsOlderThan(18); } void robocallDrinkers() { robocallPersonsOlderThan(21); } 14 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 15. Additional Use Case   Commercial pilots have mandatory retirement age of 65   Previously we parameterized a value   Now, we want to parameterize less-than or greater-than –  Add a boolean? 15 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 16. Boolean Parameter Encodes Less-or-Greater void robocallPersonsWithAgeLimit(int age, boolean lessThan) { List<Person> list = gatherPersons(); for (Person p : list) { if ( lessThan && (p.getAge() < age) || !lessThan && (p.getAge() >= age)) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } } 16 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 17. Using the Boolean Parameter void robocallEligibleDrivers() { robocallPersonsWithAgeLimit(16, false); } void robocallEligibleVoters() { robocallPersonsWithAgeLimit(18, false); } void robocallLegalDrinkers() { robocallPersonsWithAgeLimit(21, false); } void robocallEligiblePilots() { robocallPersonsWithAgeLimit(65, true); } 17 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 18. Let’s face it, this sucks 18 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 19. Corrected Use Case   Commercial pilots also have a minimum age of 23 –  as well as a mandatory retirement age of 65   Use an age range instead... 19 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 20. Parameters for Age Range void robocallPersonsInAgeRange(int low, int high) { List<Person> list = gatherPersons(); for (Person p : list) { if (low <= p.getAge() && p.getAge() < high) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } } 20 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 21. Using Age Range Integer.MAX_VALUE void robocallEligibleDrivers() { robocallPersonsInAgeRange(16, MAX); } void robocallEligibleVoters() { robocallPersonsInAgeRange(18, MAX); } void robocallLegalDrinkers() { robocallPersonsInAgeRange(21, MAX); } void robocallEligiblePilots() { robocallPersonsInAgeRange(23, 65); } 21 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 22. Additional Use Case   United States Selective Service (national service program) –  Age range 18 to 25 (inclusive) void robocallSelectiveService() { robocallPersonsInAgeRange(18, 26); } 22 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 23. Corrected Use Case   United States Selective Service enum Sex { MALE, FEMALE } –  Age range 18 to 25 (inclusive), men only   Change to: void robocallSelectiveService() { robocallPersonsInAgeRange(18, 26, MALE); }   Works, but what about queries that don’t care about sex? –  Add DONT_CARE to enum Sex? Mixes data with query value. –  Use null? (Yes, enums can be null; weird special case.) 23 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 24. Parameterized Computation   Value parameterization is useful, but only to a certain point –  Problem: meta-information is communicated “in-band” –  In these cases we need a value that means “don’t care” –  Sometimes special values can be found that work:   0, -1, Integer.MAX_VALUE, null –  If not, add more boolean, enum parameters   Just age and sex, but already we sort of need a query language   A giant leap: parameterize behavior instead of values –  Make a method’s parameter be a function instead of a value 24 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 25. Functions: Parameters and Return Values (int, int) ➞ int example: addition String ➞ int example: length Person ➞ boolean example: several, let’s revisit 25 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 26. Examples of Person → boolean Functions boolean checkIfPersonIsEligibleToDrive(Person p) { return p.getAge() >= 16; } boolean checkIfPersonIsEligibleToVote(Person p) { return p.getAge() >= 18; } boolean checkIfPersonIsLegalToDrink(Person p) { return p.getAge() >= 21; } 26 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 27. Examples of Person → boolean Functions boolean checkIfPersonIsEligiblePilot(Person p) { return p.getAge >= 23 && p.getAge() < 65; } boolean checkIfPersonEligibleForSelectiveService(Person p) { return p.getSex() == MALE && p.getAge() >= 18 && p.getAge() <= 25; } 27 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 28. How To Pass a Function in Java?   Use anonymous inner classes: new Thread( new Runnable() { public void run() { System.out.println("I'm another thread!"); } } ).start(); 28 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 29. What is the Type of a Function in Java? ( ) ➞ void interface Runnable { This is a functional interface — public void run(); an interface with a single method * } * To be precise, we should say single abstract method, since in Java 8 it is empty argument list now possible for interfaces to have implementations via the default method feature. 29 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 30. Predicate: Function Returning Boolean Person ➞ boolean interface PersonPredicate { boolean testPerson(Person p); } 30 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 31. A Generalized Predicate T ➞ boolean interface Predicate<T> { boolean test(T t); } 31 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 32. Using a Function Passed as a Parameter void robocallMatchingPersons(Predicate<Person> pred) { List<Person> list = gatherPersons(); for (Person p : list) { if (pred.test(p)) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } } 32 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 33. Passing a Function as a Parameter void robocallEligibleDrivers() { robocallMatchingPersons( new Predicate<Person>() { public boolean test(Person p) { return p.getAge() >= 16; } }); } 33 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 34. Passing a Function as a Parameter void robocallEligibleVoters() { robocallMatchingPersons( new Predicate<Person>() { public boolean test(Person p) { return p.getAge() >= 18; } }); } 34 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 35. Passing a Function as a Parameter void robocallLegalDrinkers() { robocallMatchingPersons( new Predicate<Person>() { public boolean test(Person p) { return p.getAge() >= 21; } }); } 35 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 36. Passing a Function as a Parameter void robocallEligiblePilots() { robocallMatchingPersons( new Predicate<Person>() { public boolean test(Person p) { return p.getAge() >= 23 && p.getAge() < 65; } }); } 36 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 37. Passing a Function as a Parameter void robocallSelectiveServiceCandidates() { robocallMatchingPersons( new Predicate<Person>() { public boolean test(Person p) { return p.getSex() == MALE && p.getAge() >= 18 && p.getAge() <= 25; } }); } 37 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 38. Powerful, but verbose, and very, very painful 38 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 39. The Significant Part void robocallEligibleDrivers() { robocallMatchingPersons( new Predicate<Person>() { public boolean test(Person p) { return p.getAge() >= 16; } }); } 39 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 40. The Boilerplate void robocallEligibleDrivers() { robocallMatchingPersons( new Predicate<Person>() { public boolean test(Person p) { return p.getAge() >= 16; } }); } 40 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 41. Erase the Boilerplate void robocallEligibleDrivers() { robocallMatchingPersons( p -> p.getAge() >= 16 ); } 41 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 42. Our First Lambda Expression! void robocallEligibleDrivers() { robocallMatchingPersons(p -> p.getAge() >= 16); } body parameters Lambda expressions are converted to arrow instances of functional interfaces 42 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 43. Our First Lambda Expression! void robocallEligibleDrivers() { robocallMatchingPersons(p -> p.getAge() >= 16); } Type Inference: Person ➞ boolean boolean test(Person) Target Type void robocallMatchingPersons(Predicate<Person> pred) { ... } 43 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 44. Rewrites Using Lambda void robocallEligibleDrivers() { robocallMatchingPersons(p -> p.getAge() >= 16); } void robocallEligibleVoters() { robocallMatchingPersons(p -> p.getAge() >= 18); } void robocallLegalDrinkers() { robocallMatchingPersons(p -> p.getAge() >= 21); } 44 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 45. Rewrites Using Lambda void robocallEligiblePilots() { robocallMatchingPersons( p -> p.getAge() >= 23 && p.getAge() < 65); } void robocallSelectiveServiceCandidates() { robocallMatchingPersons(p -> p.getSex() == MALE && p.getAge() >= 18 && p.getAge() <= 25); } 45 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 46. Where Else Can We Use Lambda? void robocallMatchingPersons(Predicate<Person> pred) { List<Person> list = gatherPersons(); for (Person p : list) { if (pred.test(p)) { PhoneNumber num = p.getPhoneNumber(); robocall(num); } } } 46 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 47. Where Else Can We Use Lambda? void txtmsgMatchingPersons(Predicate<Person> pred) { List<Person> list = gatherPersons(); for (Person p : list) { if (pred.test(p)) { PhoneNumber num = p.getPhoneNumber(); txtmsg(num); } } } 47 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 48. Functional Interface: Block PhoneNumber ➞ void T ➞ void interface Block<T> { void apply(T t); } 48 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 49. Extract & Parameterize Block Function void processMatchingPersons(Predicate<Person> pred, Block<PhoneNumber> block) { List<Person> list = gatherPersons(); for (Person p : list) { if (pred.test(p)) { PhoneNumber num = p.getPhoneNumber(); block.apply(num); } } } 49 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 50. Examples of Block processMatchingPersons(p -> p.getAge() >= 16, num -> { robocall(num); }); processMatchingPersons(p -> p.getAge() >= 18, num -> { txtmsg(num); }); These are “statement lambdas” as opposed to “expression lambdas” 50 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 51. What Else Can We Extract? void processMatchingPersons(Predicate<Person> pred, Block<PhoneNumber> block) { List<Person> list = gatherPersons(); for (Person p : list) { if (pred.test(p)) { PhoneNumber num = p.getPhoneNumber(); block.apply(num); } } } 51 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 52. Functional Interface: Mapper Person ➞ PhoneNumber T➞U interface Mapper<T,U> { U map(T t); } 52 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 53. Extract & Parameterize Mapper Function void processMatchingPersons(Predicate<Person> pred, Mapper<Person,PhoneNumber> mapper, Block<PhoneNumber> block) { List<Person> list = gatherPersons(); for (Person p : list) { if (pred.test(p)) { PhoneNumber num = mapper.map(p); block.apply(num); } } } 53 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 54. Examples of Mapper processMatchingPersons(p -> p.getAge() >= 16, p -> p.getHomePhoneNumber(), num -> { robocall(num); }); processMatchingPersons(p -> p.getAge() >= 18, p -> p.getMobilePhoneNumber(), num -> { txtmsg(num); }); 54 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 55. Refactoring & Cleanup void processMatchingPersons(Predicate<Person> pred, Mapper<Person,PhoneNumber> mapper, Block<PhoneNumber> block) { List<Person> list = gatherPersons(); for (Person p : list) { if (pred.test(p)) { PhoneNumber num = mapper.map(p); block.apply(num); } } } 55 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 56. Refactoring & Cleanup void processMatchingPersons(List<Person> list, Predicate<Person> pred, Mapper<Person,PhoneNumber> mapper, Block<PhoneNumber> block) { for (Person p : list) { if (pred.test(p)) { PhoneNumber num = mapper.map(p); block.apply(num); } } } 56 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 57. Refactoring & Cleanup void processMatchingPersons(Iterable<Person> source, Predicate<Person> pred, Mapper<Person,PhoneNumber> mapper, Block<PhoneNumber> block) { for (Person p : source) { if (pred.test(p)) { PhoneNumber num = mapper.map(p); block.apply(num); } } } 57 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 58. Usage After Refactoring // robocall eligible drivers processMatchingPersons(gatherPersons(), p -> p.getAge() >= 16, p -> p.getHomePhoneNumber(), num -> { robocall(num); }); // text-message eligible voters processMatchingPersons(gatherPersons(), p -> p.getAge() >= 18, p -> p.getMobilePhoneNumber(), num -> { txtmsg(num); }); 58 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 59. What Does processMatchingPersons Really Do? void processMatchingPersons(Iterable<Person> source, Predicate<Person> pred, Mapper<Person,PhoneNumber> mapper, Block<PhoneNumber> block) { for (Person p : source) { if (pred.test(p)) { PhoneNumber num = mapper.map(p); block.apply(num); } } } 59 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 60. What Does processMatchingPersons Really Do? << source provides Person objects >> { << filter each Person through a predicate >> { << map each Person to a PhoneNumber >> << apply a function to each PhoneNumber >> } } 60 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 61. A General Form of processMatchingPersons << source provides elements >> { << filter each through a predicate >> { << map each value to another value >> << apply a function to each value >> } } 61 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 62. A General Form of processMatchingPersons lambda lambda lambda Source Filter Mapper Apply 62 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 63. OK great, but can we really write the code this way? 63 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 64. Building a Pipeline for Robocalling void robocallEligibleDrivers() { gatherPersons() 64 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 65. Building a Pipeline for Robocalling void robocallEligibleDrivers() { gatherPersons().stream() .filter(...) .map(...) .forEach(...); } Source Filter Mapper Apply 65 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 66. Building a Pipeline void robocallEligibleDrivers() { gatherPersons().stream() .filter(p -> p.getAge() >= 16) .map(p -> p.getHomePhoneNumber()) .forEach(num -> { robocall(num); }); } lambda lambda lambda Source Filter Mapper Apply 66 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 67. Changing the Pipeline void robocallEligibleDrivers() { gatherPersons().stream() .filter(p -> p.getAge() >= 16) .map(p -> p.getHomePhoneNumber()) .filter(num -> !num.isOnDoNotCallList()) .forEach(num -> { robocall(num); }); } 67 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 68. Changing the Pipeline void textMessageEligibleDrivers() { gatherPersons().stream() .filter(p -> p.getAge() >= 16) .map(p -> p.getMobilePhoneNumber()) .filter(num -> !num.isOnDoNotCallList()) .forEach(num -> { txtmsg(num); }); } 68 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 69. Changing the Pipeline void spamEligibleDrinkers() { gatherPersons().stream() .filter(p -> p.getAge() >= 21) .map(p -> p.getEmailAddr()) .forEach(addr -> { sendEmail(addr); }); } 69 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 70. Changing the Pipeline void bulkMailEligiblePilots() { gatherPersons().stream() .filter(p -> p.getAge() >= 23 && p.getAge() < 65) .map(p -> p.getPostalAddr()) .forEach(addr -> { sendBulkMail(addr); }); } 70 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 71. Changing the Pipeline void recruitSelectiveServiceCandidates() { gatherPersons().stream() .filter(p -> p.getSex() == MALE && p.getAge() >= 18 && p.getAge() <= 25) .map(p -> p.getHomeAddr()) .forEach(addr -> { sendArmyRecruiter(addr); }); } 71 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 72. How To Do Stuff in Parallel? void robocallEligibleDrivers() { gatherPersons().parallel() .stream() .filter(p -> p.getAge() >= 16) .map(p -> p.getHomePhoneNumber()) .forEach(num -> { robocall(num); }); } 72 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 73. Functional Interfaces in java.util.functions BinaryOperator<T> (T, T) ➞ T Block<T> T ➞ void Combiner<T,U,V> (T, U) ➞ V Factory<T> () ➞ T FlatMapper<T,R> T ➞ R* Mapper<T,U> T➞U Predicate<T> T ➞ boolean UnaryOperator<T> T➞T 73 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 74. Stream Operations java.util.stream.Stream   filter(pred)   toArray(array-factory)   map(mapper)   any / all / noneMatch(pred)   forEach(block)   findFirst / Any(pred)   flatMap(flat-mapper)   cumulate(binop)   tee(block)   reduce(binop) / reduce(base, binop)   uniqueElements()   fold(base-factory, reducer, combiner)   sorted(comparator)   groupBy(mapper)   into(collection)   reduceBy(mapper, base-factory, reducer) 74 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 75. Summary   Lambdas are anonymous functions –  They enable parameterization of behavior   Lambda expressions are converted to functional interfaces –  A functional interface is an interface with a single (abstract) method   Two kinds: expression lambdas and statement lambdas   Compiler type inference reduces boilerplate   Lambda + new library APIs enable writing programs that are: –  powerful, fluid, expressive, parallel 75 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 76. Related Talks – All Brian Goetz, All The Time   The Road To Lambda (earlier J1 talk)   Lambda: A Peek Under the Hood (earlier J1 talk)   Implementing Lambda Expressions in Java –  JVM Language Summit 2012 –  http://www.oracle.com/technetwork/java/ javase/community/jvmls2012-1840099.html λ   Language / Library / VM Co-evolution in Java SE 8, Devoxx 2011 –  https://blogs.oracle.com/briangoetz/entry/slides_from_devoxx_talk_on 76 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 77. Links   Lambda project page: http://openjdk.java.net/projects/lambda/   Source code: http://hg.openjdk.java.net/lambda/lambda   Binaries: http://jdk8.java.net/lambda/ λ   FAQ (Maurice Naftalin): http://www.lambdafaq.org/ 77 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 78. Any Questions? 78 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 79. The preceding is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle s products remains at the sole discretion of Oracle. 79 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
  • 80. Graphic Section Divider 80 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.