java se 8_ lambda quick start

27
Purpose This tutorial introduces the new lambda expressions included in Java Platform Standard Edition 8 (Java SE 8). Time to Complete Approximately 1 hour Introduction Lambda expressions are a new and important feature included in Java SE 8. They provide a clear and concise way to represent one method interface using an expression. Lambda expressions also improve the Collection libraries making it easier to iterate through, filter, and extract data from a Collection. In addition, new concurrency features improve performance in multicore environments. This Oracle by Example (OBE) provides an introduction to lambda expressions included in Java SE 8. An introduction to anonymous inner functions is provided, followed by a discussion of functional interfaces and the new lambda syntax. Then, examples of common usage patterns before and after lambda expressions are shown. The next section reviews a common search use case and how Java code can be improved with the inclusion of lambda expressions. In addition, some of the common functional interfaces, Predicate and Function, provided in java.util.function are shown in action. The OBE finishes up with a review of how the Java collection has been updated with lambda expressions. The source code for all examples is provided to you. Hardware and Software Requirements The following is a list of hardware and software requirements: Java Development Kit (JDK 8) early access Overview Java SE 8: Lambda Quick Start

Upload: bob

Post on 01-Sep-2015

230 views

Category:

Documents


1 download

Tags:

DESCRIPTION

Java SE 8_ Lambda Quick Start

TRANSCRIPT

  • Purpose

    ThistutorialintroducesthenewlambdaexpressionsincludedinJavaPlatformStandardEdition8(JavaSE8).

    TimetoComplete

    Approximately1hour

    Introduction

    LambdaexpressionsareanewandimportantfeatureincludedinJavaSE8.Theyprovideaclearandconcisewaytorepresentonemethodinterfaceusinganexpression.LambdaexpressionsalsoimprovetheCollectionlibrariesmakingiteasiertoiteratethrough,filter,andextractdatafromaCollection.Inaddition,newconcurrencyfeaturesimproveperformanceinmulticoreenvironments.

    ThisOraclebyExample(OBE)providesanintroductiontolambdaexpressionsincludedinJavaSE8.Anintroductiontoanonymousinnerfunctionsisprovided,followedbyadiscussionoffunctionalinterfacesandthenewlambdasyntax.Then,examplesofcommonusagepatternsbeforeandafterlambdaexpressionsareshown.

    ThenextsectionreviewsacommonsearchusecaseandhowJavacodecanbeimprovedwiththeinclusionoflambdaexpressions.Inaddition,someofthecommonfunctionalinterfaces,PredicateandFunction,providedinjava.util.functionareshowninaction.

    TheOBEfinishesupwithareviewofhowtheJavacollectionhasbeenupdatedwithlambdaexpressions.

    Thesourcecodeforallexamplesisprovidedtoyou.

    HardwareandSoftwareRequirements

    Thefollowingisalistofhardwareandsoftwarerequirements:

    JavaDevelopmentKit(JDK8)earlyaccess

    Overview

    JavaSE8:LambdaQuickStart

  • JavaDevelopmentKit(JDK8)earlyaccessNetBeans7.4

    PrerequisitesToruntheexamples,youmusthaveanearlyaccessversionofJDK8andacopyofNetBeans7.4orlater.LinkscanbefoundatthemainLambdasite.Foryourconvenience,herearethedirectlinks.

    JavaDevelopmentKit8(JDK8)EarlyAccessRecommended:DownloadtheJDK8APIDocsfromthesamepage.

    NetBeans7.4orlater.Version7.4ofNetBeansincludessupportforJDK8.

    Note:Buildsareprovidedforallmajoroperatingsystems.ThisOBEwasdevelopedusingLinuxMint13(Ubuntu/Debian).

    InstallJDK8andNetBeansfollowingtheinstructionsprovidedwiththedownloads.AddthebindirectoriesforJavaandNetBeanstoyourPATH.

    Note:ThisOBEwaslastupdatedDecember2013.

    AnonymousInnerClass

    InJava,anonymousinnerclassesprovideawaytoimplementclassesthatmayoccuronlyonceinanapplication.Forexample,inastandardSwingorJavaFXapplicationanumberofeventhandlersarerequiredforkeyboardandmouseevents.Ratherthanwritingaseparateeventhandlingclassforeachevent,youcanwritesomethinglikethis.

    16 JButton testButton = new JButton("Test Button");17 testButton.addActionListener(new ActionListener(){18 @Override public void actionPerformed(ActionEvent ae){19 System.out.println("Click Detected by Anon Class");20 }21 });

    Otherwise,aseparateclassthatimplementsActionListenerisrequiredforeachevent.Bycreatingtheclassinplace,whereitisneeded,thecodeisalittleeasiertoread.Thecodeisnotelegant,becausequiteabitofcodeisrequiredjusttodefineonemethod.

    FunctionalInterfaces

    ThecodethatdefinestheActionListenerinterface,lookssomethinglikethis:

    Background

    https://jdk8.java.net/download.htmlhttp://openjdk.java.net/projects/lambda/http://netbeans.org/
  • this:

    1 package java.awt.event; 2 import java.util.EventListener; 3 4 public interface ActionListener extends EventListener { 5 6 public void actionPerformed(ActionEvent e); 7 8 }

    TheActionListenerexampleisaninterfacewithonlyonemethod.WithJavaSE8,aninterfacethatfollowsthispatternisknownasa"functionalinterface."

    Note:Thistypeofinterface,waspreviouslyknownasaSingleAbstractMethodtype(SAM).

    UsingfunctionalinterfaceswithanonymousinnerclassesareacommonpatterninJava.InadditiontotheEventListenerclasses,interfaceslikeRunnableandComparatorareusedinasimilarmanner.Therefore,functionalinterfacesareleveragedforusewithlambdaexpressions.

    LambdaExpressionSyntax

    Lambdaexpressionsaddressthebulkinessofanonymousinnerclassesbyconvertingfivelinesofcodeintoasinglestatement.Thissimplehorizontalsolutionsolvesthe"verticalproblem"presentedbyinnerclasses.

    Alambdaexpressioniscomposedofthreeparts.

    ArgumentList ArrowToken Body

    (intx,inty)

    > x+y

    Thebodycanbeeitherasingleexpressionorastatementblock.Intheexpressionform,thebodyissimplyevaluatedandreturned.Intheblockform,thebodyisevaluatedlikeamethodbodyandareturnstatementreturnscontroltothecalleroftheanonymousmethod.Thebreakandcontinuekeywordsareillegalatthetoplevel,butarepermittedwithinloops.Ifthebodyproducesaresult,everycontrolpathmustreturnsomethingorthrowanexception.

    Takealookattheseexamples:

    (int x, int y) -> x + y

    () -> 42

    (String s) -> { System.out.println(s); }

  • Thefirstexpressiontakestwointegerarguments,namedxandy,anduses

    theexpressionformtoreturnx+y.Thesecondexpressiontakesnoargumentsandusestheexpressionformtoreturnaninteger42.Thethirdexpressiontakesastringandusestheblockformtoprintthestringtotheconsole,andreturnsnothing.

    Withthebasicsofsyntaxcovered,let'slookatsomeexamples.

    Herearesomecommonusecasesusingthepreviouslycoveredexamples.

    RunnableLambda

    HereishowyouwriteaRunnableusinglambdas.

    6 public class RunnableTest { 7 public static void main(String[] args) { 8 9 System.out.println("=== RunnableTest ===");10 11 // Anonymous Runnable12 Runnable r1 = new Runnable(){13 14 @Override15 public void run(){16 System.out.println("Hello world one!");17 }18 };19 20 // Lambda Runnable21 Runnable r2 = () -> System.out.println("Hello world two!");22 23 // Run em!24 r1.run();25 r2.run();26 27 }28 }

    Inbothcases,noticethatnoparameterispassedandisreturned.TheRunnablelambdaexpression,whichusestheblockformat,convertsfivelinesofcodeintoonestatement.

    ComparatorLambda

    InJava,theComparatorclassisusedforsortingcollections.Inthefollowingexample,anArrayListconsistingofPersonobjectsissortedbasedon

    LambdaExamples

  • surName.ThefollowingarethefieldsincludedinthePersonclass.

    9 public class Person {

    10 private String givenName;11 private String surName;12 private int age;13 private Gender gender;14 private String eMail;15 private String phone;16 private String address;17

    ThefollowingcodeappliesaComparatorbyusingananonymousinnerclassandacouplelambdaexpressions.

    10 public class ComparatorTest {11 12 public static void main(String[] args) {13 14 List personList = Person.createShortList();15 16 // Sort with Inner Class17 Collections.sort(personList, new Comparator(){18 public int compare(Person p1, Person p2){19 return p1.getSurName().compareTo(p2.getSurName());20 }21 });22 23 System.out.println("=== Sorted Asc SurName ===");24 for(Person p:personList){25 p.printName();26 }27 28 // Use Lambda instead29 30 // Print Asc31 System.out.println("=== Sorted Asc SurName ===");32 Collections.sort(personList, (Person p1, Person p2) -> p1.getSurName().compareTo(p2.getSurName()));33 34 for(Person p:personList){35 p.printName();36 }37 38 // Print Desc39 System.out.println("=== Sorted Desc SurName ===");40 Collections.sort(personList, (p1, p2) -> p2.getSurName().compareTo(p1.getSurName()));41 42 for(Person p:personList){43 p.printName();44 }45 46 }47 }

    Lines1721areeasilyreplacedbythelambdaexpressiononline32.Noticethatthefirstlambdaexpressiondeclarestheparametertypepassedtotheexpression.However,asyoucanseefromthesecondexpression,thisis

  • expression.However,asyoucanseefromthesecondexpression,thisisoptional.Lambdasupports"targettyping"whichinferstheobjecttypefromthecontextinwhichitisused.BecauseweareassigningtheresulttoaComparatordefinedwithageneric,thecompilercaninferthatthetwoparametersareofthePersontype.

    ListenerLambda

    Finally,let'srevisittheActionListenerexample.

    13 public class ListenerTest {14 public static void main(String[] args) {15 16 JButton testButton = new JButton("Test Button");17 testButton.addActionListener(new ActionListener(){18 @Override public void actionPerformed(ActionEvent ae){19 System.out.println("Click Detected by Anon Class");20 }21 });22 23 testButton.addActionListener(e -> System.out.println("Click Detected by Lambda Listner"));24 25 // Swing stuff26 JFrame frame = new JFrame("Listener Test");27 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);28 frame.add(testButton, BorderLayout.CENTER);29 frame.pack();30 frame.setVisible(true);31 32 }33 }

    Noticethatthelambdaexpressionispassedasaparameter.Targettypingisusedinanumberofcontextsincludingthefollowing:

    VariabledeclarationsAssignmentsReturnstatementsArrayinitializersMethodorconstructorargumentsLambdaexpressionbodiesConditionalexpressions?:Castexpressions

    Resources

    ANetBeansprojectcontainingthesourcefilesfortheexamplescoveredtothispointisinthefollowingzipfile.

    LambdaExamples01.zip

    http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/examples/LambdaExamples01.zip
  • Thissectionbuildsuponthepreviousexamplestoshowyouhowlambdaexpressionscanimproveyourcode.LambdasshouldprovideameanstobettersupporttheDon'tRepeatYourself(DRY)principleandmakeyourcodesimplerandmorereadable.

    ACommonQueryUseCase

    Acommonusecaseforprogramsistosearchthroughacollectionofdatatofinditemsthatmatchaspecificcriteria.Intheexcellent"JumpStartingLambda"presentationatJavaOne2012,StuartMarksandMikeDuigouwalkthoughjustsuchausecase.Givenalistofpeople,variouscriteriaareusedtomakerobocalls(automatedphonecalls)tomatchingpersons.Thistutorialfollowsthatbasicpremisewithslightvariations.

    Inthisexample,ourmessageneedstogetouttothreedifferentgroupsintheUnitedStates:

    Drivers:Personsovertheageof16Draftees:Malepersonsbetweentheagesof18and25Pilots(specificallycommercialpilots):Personsbetweentheagesof23and65

    Theactualrobotthatdoesallthisworkhasnotyetarrivedatourplaceofbusiness.Insteadofcalling,mailingoremailing,amessageisprintedtotheconsole.Themessagecontainsaperson'sname,age,andinformationspecifictothetargetmedium(forexample,emailaddresswhenemailingorphonenumberwhencalling).

    PersonClass

    EachpersoninthetestlistisdefinedbyusingthePersonclasswiththefollowingproperties:

    10 public class Person {11 private String givenName;12 private String surName;13 private int age;14 private Gender gender;15 private String eMail;16 private String phone;17 private String address;18

    ThePersonclassusesaBuildertocreatenewobjects.AsamplelistofpeopleiscreatedwiththecreateShortListmethod.Hereisashortcodefragmentofthatmethod.Note:AllsourcecodeforthistutorialisincludedinaNetBeansprojectthatislinkedattheendofthissection.

    ImprovingCodewithLambdaExpressions

    http://www.youtube.com/watch?v=bzO5GSujdqI
  • 128 public static List createShortList(){129 List people = new ArrayList();130 131 people.add(132 new Person.Builder()133 .givenName("Bob")134 .surName("Baker")135 .age(21)136 .gender(Gender.MALE)137 .email("[email protected]")138 .phoneNumber("201-121-4678")139 .address("44 4th St, Smallville, KS 12333")140 .build() 141 );142 143 people.add(144 new Person.Builder()145 .givenName("Jane")146 .surName("Doe")147 .age(25)148 .gender(Gender.FEMALE)149 .email("[email protected]")150 .phoneNumber("202-123-4678")151 .address("33 3rd St, Smallville, KS 12333")152 .build() 153 );154 155 people.add(156 new Person.Builder()157 .givenName("John")158 .surName("Doe")159 .age(25)160 .gender(Gender.MALE)161 .email("[email protected]")162 .phoneNumber("202-123-4678")163 .address("33 3rd St, Smallville, KS 12333")164 .build()165 );166

    AFirstAttempt

    WithaPersonclassandsearchcriteriadefined,youcanwriteaRoboContactclass.Onepossiblesolutiondefinesamethodforeachusecase:

    RoboContactsMethods.java

    1 package com.example.lambda; 2 3 import java.util.List; 4 5 /** 6 * 7 * @author MikeW 8 */ 9 public class RoboContactMethods { 10 11 public void callDrivers(List pl){ 12 for(Person p:pl){

  • 12 for(Person p:pl){ 13 if (p.getAge() >= 16){ 14 roboCall(p); 15 } 16 } 17 } 18 19 public void emailDraftees(List pl){ 20 for(Person p:pl){ 21 if (p.getAge() >= 18 && p.getAge() = 23 && p.getAge()

  • RoboContactMethods2.java

    1 package com.example.lambda; 2 3 import java.util.List; 4 5 /** 6 * 7 * @author MikeW 8 */ 9 public class RoboContactMethods2 { 10 11 public void callDrivers(List pl){ 12 for(Person p:pl){ 13 if (isDriver(p)){ 14 roboCall(p); 15 } 16 } 17 } 18 19 public void emailDraftees(List pl){ 20 for(Person p:pl){ 21 if (isDraftee(p)){ 22 roboEmail(p); 23 } 24 } 25 } 26 27 public void mailPilots(List pl){ 28 for(Person p:pl){ 29 if (isPilot(p)){ 30 roboMail(p); 31 } 32 } 33 } 34 35 public boolean isDriver(Person p){ 36 return p.getAge() >= 16; 37 } 38 39 public boolean isDraftee(Person p){ 40 return p.getAge() >= 18 && p.getAge() = 23 && p.getAge()

  • 57 } 58 59 }

    Thesearchcriteriaareencapsulatedinamethod,animprovementoverthepreviousexample.Thetestconditionscanbereusedandchangesflowbackthroughouttheclass.Howeverthereisstillalotofrepeatedcodeandaseparatemethodisstillrequiredforeachusecase.Isthereabetterwaytopassthesearchcriteriatothemethods?

    AnonymousClasses

    Beforelambdaexpressions,anonymousinnerclasseswereanoption.Forexample,aninterface(MyTest.java)writtenwithonetestmethodthatreturnsaboolean(afunctionalinterface)isapossiblesolution.Thesearchcriteriacouldbepassedwhenthemethodiscalled.Theinterfacelookslikethis:

    6 public interface MyTest {7 public boolean test(T t);8 }

    Theupdatedrobotclasslookslikethis:

    RoboContactsAnon.java

    9 public class RoboContactAnon {10 11 public void phoneContacts(List pl, MyTest aTest){12 for(Person p:pl){13 if (aTest.test(p)){14 roboCall(p);15 }16 }17 }18 19 public void emailContacts(List pl, MyTest aTest){20 for(Person p:pl){21 if (aTest.test(p)){22 roboEmail(p);23 }24 }25 }26 27 public void mailContacts(List pl, MyTest aTest){28 for(Person p:pl){29 if (aTest.test(p)){30 roboMail(p);31 }32 }33 } 34

  • 34 35 public void roboCall(Person p){36 System.out.println("Calling " + p.getGivenName() + " " + p.getSurName() + " age " + p.getAge() + " at " + p.getPhone());37 }

    38 39 public void roboEmail(Person p){40 System.out.println("EMailing " + p.getGivenName() + " " + p.getSurName() + " age " + p.getAge() + " at " + p.getEmail());41 }42 43 public void roboMail(Person p){44 System.out.println("Mailing " + p.getGivenName() + " " + p.getSurName() + " age " + p.getAge() + " at " + p.getAddress());45 }46 47 }

    Thatisdefinitelyanotherimprovement,becauseonlythreemethodsareneededtoperformroboticoperations.However,thereisaslightproblemwithuglinesswhenthemethodsarecalled.Checkoutthetestclassusedforthisclass:

    RoboCallTest03.java

    1 package com.example.lambda; 2 3 import java.util.List; 4 5 /** 6 * @author MikeW 7 */ 8 public class RoboCallTest03 { 9 10 public static void main(String[] args) { 11 12 List pl = Person.createShortList(); 13 RoboContactAnon robo = new RoboContactAnon(); 14 15 System.out.println("\n==== Test 03 ===="); 16 System.out.println("\n=== Calling all Drivers ==="); 17 robo.phoneContacts(pl, 18 new MyTest(){ 19 @Override 20 public boolean test(Person p){ 21 return p.getAge() >=16; 22 } 23 } 24 ); 25 26 System.out.println("\n=== Emailing all Draftees ==="); 27 robo.emailContacts(pl, 28 new MyTest(){ 29 @Override 30 public boolean test(Person p){ 31 return p.getAge() >= 18 && p.getAge()

  • 34 ); 35 36 37 System.out.println("\n=== Mail all Pilots ==="); 38 robo.mailContacts(pl,

    39 new MyTest(){ 40 @Override 41 public boolean test(Person p){ 42 return p.getAge() >= 23 && p.getAge()

  • 10 public class RoboContactLambda { 11 public void phoneContacts(List pl, Predicate pred){ 12 for(Person p:pl){ 13 if (pred.test(p)){ 14 roboCall(p); 15 } 16 } 17 } 18 19 public void emailContacts(List pl, Predicate pred){ 20 for(Person p:pl){ 21 if (pred.test(p)){ 22 roboEmail(p); 23 } 24 } 25 } 26 27 public void mailContacts(List pl, Predicate pred){ 28 for(Person p:pl){ 29 if (pred.test(p)){ 30 roboMail(p); 31 } 32 } 33 } 34 35 public void roboCall(Person p){ 36 System.out.println("Calling " + p.getGivenName() + " " + p.getSurName() + " age " + p.getAge() + " at " + p.getPhone()); 37 } 38 39 public void roboEmail(Person p){ 40 System.out.println("EMailing " + p.getGivenName() + " " + p.getSurName() + " age " + p.getAge() + " at " + p.getEmail()); 41 } 42 43 public void roboMail(Person p){ 44 System.out.println("Mailing " + p.getGivenName() + " " + p.getSurName() + " age " + p.getAge() + " at " + p.getAddress()); 45 } 46 47 }

    Withthisapproachonlythreemethodsareneeded,oneforeachcontactmethod.ThelambdaexpressionpassedtothemethodselectsthePersoninstancesthatmeetthetestconditions.

    VerticalProblemSolved

    Lambdaexpressionssolvetheverticalproblemandallowtheeasyreuseofanyexpression.Takealookatthenewtestclassupdatedforlambdaexpressions.

    RoboCallTest04.java

    1 package com.example.lambda;

  • 1 package com.example.lambda; 2 3 import java.util.List; 4 import java.util.function.Predicate; 5

    6 /** 7 * 8 * @author MikeW 9 */ 10 public class RoboCallTest04 { 11 12 public static void main(String[] args){ 13 14 List pl = Person.createShortList(); 15 RoboContactLambda robo = new RoboContactLambda(); 16 17 // Predicates 18 Predicate allDrivers = p -> p.getAge() >= 16; 19 Predicate allDraftees = p -> p.getAge() >= 18 && p.getAge() p.getAge() >= 23 && p.getAge()

  • Thejava.util.functionPackage

    Ofcourse,PredicateisnottheonlyfunctionalinterfaceprovidedwithJavaSE8.Anumberofstandardinterfacesaredesignedasastartersetfor

    developers.

    Predicate:ApropertyoftheobjectpassedasargumentConsumer:AnactiontobeperformedwiththeobjectpassedasargumentFunction:TransformaTtoaUSupplier:ProvideaninstanceofaT(suchasafactory)UnaryOperator:AunaryoperatorfromT>TBinaryOperator:Abinaryoperatorfrom(T,T)>T

    Inaddition,manyoftheseinterfacesalsohaveprimitiveversions.Thisshouldgiveyouagreatstartingpointforyourlambdaexpressions.

    EasternStyleNamesandMethodReferences

    Whenworkingonthepreviousexample,IdecideditwouldbenicetohaveaflexibleprintingsystemforthePersonclass.Onefeaturerequirementistodisplaynamesinbothawesternstyleandaneasternstyle.IntheWest,namesaredisplayedwiththegivennamefirstandthesurnamesecond.Inmanyeasterncultures,namesaredisplayedwiththesurnamefirstandthegivennamesecond.

    AnOldStyleExample

    HereisanexampleofhowtoimplementaPersonprintingclasswithoutlambdasupport.

    Person.java

    128 public void printWesternName(){129 130 System.out.println("\nName: " + this.getGivenName() + " " + this.getSurName() + "\n" +131 "Age: " + this.getAge() + " " + "Gender: " + this.getGender() + "\n" +132 "EMail: " + this.getEmail() + "\n" + 133 "Phone: " + this.getPhone() + "\n" +134 "Address: " + this.getAddress());135 }136 137 138 139 public void printEasternName(){140 141 System.out.println("\nName: " + this.getSurName() + " " + this.getGivenName() + "\n" +142 "Age: " + this.getAge() + " " + "Gender: " + this.getGender() + "\n" +143 "EMail: " + this.getEmail() + "\n" + 144 "Phone: " + this.getPhone() + "\n" +

  • 144 "Phone: " + this.getPhone() + "\n" +145 "Address: " + this.getAddress());146 }

    Amethodexistsforeachstylethatprintsoutaperson.

    TheFunctionInterface

    TheFunctioninterfaceisusefulforthisproblem.Ithasonlyonemethodapplywiththefollowingsignature:

    publicRapply(Tt){}

    IttakesagenericclassTandreturnsagenericclassR.Forthisexample,passthePersonclassandreturnaString.Amoreflexibleprintmethodforpersoncouldbewrittenlikethis:

    Person.java

    123 public String printCustom(Function f){124 return f.apply(this);125 }126

    Thatisquiteabitsimpler.AFunctionispassedtothemethodandastringreturned.TheapplymethodprocessesalambdaexpressionwhichdetermineswhatPersoninformationisreturned.

    HowaretheFunctionsdefined?Hereisthetestcodethatcallsthepreviousmethod.

    NameTestNew.java

    9 public class NameTestNew {10 11 public static void main(String[] args) {12 13 System.out.println("\n==== NameTestNew02 ===");14 15 List list1 = Person.createShortList();16 17 // Print Custom First Name and e-mail18 System.out.println("===Custom List===");19 for (Person person:list1){20 System.out.println(21 person.printCustom(p -> "Name: " + p.getGivenName() + " EMail: " + p.getEmail())22 );23 }24 25 26 // Define Western and Eastern Lambdas

  • 26 // Define Western and Eastern Lambdas27 28 Function westernStyle = p -> {29 return "\nName: " + p.getGivenName() + " " + p.getSurName() + "\n" +

    30 "Age: " + p.getAge() + " " + "Gender: " + p.getGender() + "\n" +31 "EMail: " + p.getEmail() + "\n" + 32 "Phone: " + p.getPhone() + "\n" +33 "Address: " + p.getAddress();34 };35 36 Function easternStyle = p -> "\nName: " + p.getSurName() + " " 37 + p.getGivenName() + "\n" + "Age: " + p.getAge() + " " + 38 "Gender: " + p.getGender() + "\n" +39 "EMail: " + p.getEmail() + "\n" + 40 "Phone: " + p.getPhone() + "\n" +41 "Address: " + p.getAddress(); 42 43 // Print Western List44 System.out.println("\n===Western List===");45 for (Person person:list1){46 System.out.println(47 person.printCustom(westernStyle)48 );49 }50 51 // Print Eastern List52 System.out.println("\n===Eastern List===");53 for (Person person:list1){54 System.out.println(55 person.printCustom(easternStyle)56 );57 }58 59 60 }61 }

    Thefirstloopjustprintsgivennameandtheemailaddress.ButanyvalidexpressioncouldbepassedtotheprintCustommethod.Easternandwesternprintstylesaredefinedwithlambdaexpressionsandstoredinavariable.Thevariablesarethenpassedtothefinaltwoloops.ThelambdaexpressionscouldveryeasilybeincorporatedintoaMaptomaketheirreusemucheasier.Thelambdaexpressionprovidesagreatdealofflexibility.

    SampleOutput

    Hereissomesampleoutputfromtheprogram.

    ==== NameTestNew02 ======Custom List===Name: Bob EMail: [email protected]: Jane EMail: [email protected]: John EMail: [email protected]: James EMail: [email protected]: Joe EMail: [email protected]

  • Name: Joe EMail: [email protected]: Phil EMail: phil.smith@examp;e.comName: Betty EMail: [email protected]

    ===Western List===

    Name: Bob BakerAge: 21 Gender: MALEEMail: [email protected]: 201-121-4678Address: 44 4th St, Smallville, KS 12333

    Name: Jane DoeAge: 25 Gender: FEMALEEMail: [email protected]: 202-123-4678Address: 33 3rd St, Smallville, KS 12333

    Name: John DoeAge: 25 Gender: MALEEMail: [email protected]: 202-123-4678Address: 33 3rd St, Smallville, KS 12333

    Name: James JohnsonAge: 45 Gender: MALEEMail: [email protected]: 333-456-1233Address: 201 2nd St, New York, NY 12111

    Name: Joe BaileyAge: 67 Gender: MALEEMail: [email protected]: 112-111-1111Address: 111 1st St, Town, CA 11111

    Name: Phil SmithAge: 55 Gender: MALEEMail: phil.smith@examp;e.comPhone: 222-33-1234Address: 22 2nd St, New Park, CO 222333

    Name: Betty JonesAge: 85 Gender: FEMALEEMail: [email protected]: 211-33-1234Address: 22 4th St, New Park, CO 222333

    ===Eastern List===

    Name: Baker BobAge: 21 Gender: MALEEMail: [email protected]: 201-121-4678Address: 44 4th St, Smallville, KS 12333

    Name: Doe JaneAge: 25 Gender: FEMALEEMail: [email protected]: 202-123-4678Address: 33 3rd St, Smallville, KS 12333

    Name: Doe JohnAge: 25 Gender: MALEEMail: [email protected]: 202-123-4678Address: 33 3rd St, Smallville, KS 12333

  • Address: 33 3rd St, Smallville, KS 12333

    Name: Johnson JamesAge: 45 Gender: MALEEMail: [email protected]: 333-456-1233Address: 201 2nd St, New York, NY 12111

    Name: Bailey JoeAge: 67 Gender: MALEEMail: [email protected]: 112-111-1111Address: 111 1st St, Town, CA 11111

    Name: Smith PhilAge: 55 Gender: MALEEMail: phil.smith@examp;e.comPhone: 222-33-1234Address: 22 2nd St, New Park, CO 222333

    Name: Jones BettyAge: 85 Gender: FEMALEEMail: [email protected]: 211-33-1234Address: 22 4th St, New Park, CO 222333

    Resources

    TheNetBeansprojectwiththesourcecodefortheexamplesinthissectionisincludedinthefollowingzipfile.

    LambdaFunctionExamples.zip

    TheprevioussectionintroducedtheFunctioninterfaceandfinishedupexamplesofbasiclambdaexpressionsyntax.ThissectionreviewshowlambdaexpressionsimprovetheCollectionclasses.

    LambdaExpressionsandCollections

    Intheexamplescreatedsofar,thecollectionsclasseswereusedquiteabit.However,anumberofnewlambdaexpressionfeatureschangethewaycollectionsareused.Thissectionintroducesafewofthesenewfeatures.

    ClassAdditions

    Thedrivers,pilots,anddrafteessearchcriteriahavebeenencapsulatedintheSearchCriteriaclass.

    SearchCriteria.java

    LambdaExpressionsandCollections

    http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/examples/LambdaFunctionExamples.zip
  • SearchCriteria.java

    1 package com.example.lambda; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 import java.util.function.Predicate; 6 7 /** 8 * 9 * @author MikeW10 */11 public class SearchCriteria {12 13 private final Map searchMap = new HashMap();14 15 private SearchCriteria() {16 super();17 initSearchMap();18 }19 20 private void initSearchMap() {21 Predicate allDrivers = p -> p.getAge() >= 16;22 Predicate allDraftees = p -> p.getAge() >= 18 && p.getAge() p.getAge() >= 23 && p.getAge()

  • ThefirstfeaturetolookatisthenewforEachmethodavailabletoanycollectionclass.HereareacoupleofexamplesthatprintoutaPersonlist.

    Test01ForEach.java

    11 public class Test01ForEach {12 13 public static void main(String[] args) {14 15 List pl = Person.createShortList();16 17 System.out.println("\n=== Western Phone List ===");18 pl.forEach( p -> p.printWesternName() );19 20 System.out.println("\n=== Eastern Phone List ===");21 pl.forEach(Person::printEasternName);22 23 System.out.println("\n=== Custom Phone List ===");24 pl.forEach(p -> { System.out.println(p.printCustom(r -> "Name: " + r.getGivenName() + " EMail: " + r.getEmail())); });25 26 }27 28 }

    ThefirstexampleshowsastandardlambdaexpressionwhichcallstheprintWesternNamemethodtoprintouteachpersoninthelist.Thesecondexampledemonstratesamethodreference.Inacasewhereamethodalreadyexiststoperformanoperationontheclass,thissyntaxcanbeusedinsteadofthenormallambdaexpressionsyntax.Finally,thelastexampleshowshowtheprintCustommethodcanalsobeusedinthissituation.Noticetheslightvariationinvariablenameswhenonelambdaexpressionisincludedinanother.

    Youcaniteratethroughanycollectionthisway.Thebasicstructureissimilartotheenhancedforloop.However,includinganiterationmechanismwithintheclassprovidesanumberofbenefits.

    ChainingandFilters

    Inadditiontoloopingthroughthecontentsofacollection,youcanchainmethodstogether.ThefirstmethodtolookatisfilterwhichtakesaPredicateinterfaceasaparameter.

    ThefollowingexampleloopsthoughaListafterfirstfilteringtheresults.

    Test02Filter.java

    9 public class Test02Filter {10 11 public static void main(String[] args) {

  • 11 public static void main(String[] args) {12 13 List pl = Person.createShortList();14 15 SearchCriteria search = SearchCriteria.getInstance();

    16 17 System.out.println("\n=== Western Pilot Phone List ===");18 19 pl.stream().filter(search.getCriteria("allPilots"))20 .forEach(Person::printWesternName);21 22 23 System.out.println("\n=== Eastern Draftee Phone List ===");24 25 pl.stream().filter(search.getCriteria("allDraftees"))26 .forEach(Person::printEasternName);27 28 }29 }

    ThefirstandlastloopsdemonstratehowtheListisfilteredbasedonthesearchcriteria.Theoutputfromthelastlooplookslikefollowing:

    === Eastern Draftee Phone List ===

    Name: Baker BobAge: 21 Gender: MALEEMail: [email protected]: 201-121-4678Address: 44 4th St, Smallville, KS 12333

    Name: Doe JohnAge: 25 Gender: MALEEMail: [email protected]: 202-123-4678Address: 33 3rd St, Smallville, KS 12333

    GettingLazy

    Thesefeaturesareuseful,butwhyaddthemtothecollectionsclasseswhenthereisalreadyaperfectlygoodforloop?Bymovingiterationfeaturesintoalibrary,itallowsthedevelopersofJavatodomorecodeoptimizations.Toexplainfurther,acoupleoftermsneeddefinitions.

    Laziness:Inprogramming,lazinessreferstoprocessingonlytheobjectsthatyouwanttoprocesswhenyouneedtoprocessthem.Inthepreviousexample,thelastloopis"lazy"becauseitloopsonlythroughthetwoPersonobjectsleftaftertheListisfiltered.Thecodeshouldbemoreefficientbecausethefinalprocessingstepoccursonlyontheselectedobjects.Eagerness:Codethatperformsoperationsoneveryobjectinalistisconsidered"eager".Forexample,anenhancedforloopthatiteratesthroughanentirelisttoprocesstwoobjects,isconsideredamore"eager"approach.

    Bymakingloopingpartofthecollectionslibrary,codecanbebetteroptimized

  • Bymakingloopingpartofthecollectionslibrary,codecanbebetteroptimizedfor"lazy"operationswhentheopportunityarises.Whenamoreeagerapproachmakessense(forexample,computingasumoranaverage),eageroperationsarestillapplied.Thisapproachisamuchmoreefficientandflexiblethanalwaysusingeageroperations.

    ThestreamMethod

    Inthepreviouscodeexample,noticethatthestreammethodiscalledbeforefilteringandloopingbegin.ThismethodtakesaCollectionasinputandreturnsajava.util.stream.Streaminterfaceastheoutput.AStreamrepresentsasequenceofelementsonwhichvariousmethodscanbechained.Bydefault,onceelementsareconsumedtheyarenolongeravailablefromthestream.Therefore,achainofoperationscanoccuronlyonceonaparticularStream.Inaddition,aStreamcanbeserial(default)orparalleldependingonthemethodcalled.Anexampleofaparallelstreamisincludedattheendofthissection.

    MutationandResults

    Aspreviouslymentioned,aStreamisdisposedofafteritsuse.Therefore,theelementsinacollectioncannotbechangedormutatedwithaStream.However,whatifyouwanttokeepelementsreturnedfromyourchainedoperations?Youcansavethemtoanewcollection.Thefollowingcodeshowshowtodojustthat.

    Test03toList.java

    10 public class Test03toList {11 12 public static void main(String[] args) {13 14 List pl = Person.createShortList();15 16 SearchCriteria search = SearchCriteria.getInstance();17 18 // Make a new list after filtering.19 List pilotList = pl20 .stream()21 .filter(search.getCriteria("allPilots"))22 .collect(Collectors.toList());23 24 System.out.println("\n=== Western Pilot Phone List ===");25 pilotList.forEach(Person::printWesternName);26 27 }28 29 }

    Thecollectmethodiscalledwithoneparameter,theCollectorsclass.TheCollectorsclassisabletoreturnaListorSetbasedontheresultsofthestream.Theexampleshowshowtheresultofthestreamisassignedtoa

  • thestream.TheexampleshowshowtheresultofthestreamisassignedtoanewListwhichisiteratedover.

    CalculatingwithmapThemapmethodiscommonlyusedwithfilter.Themethodtakesapropertyfromaclassanddoessomethingwithit.Thefollowingexampledemonstratesthisbyperformingcalculationsbasedonage.

    Test04Map.java

    10 public class Test04Map {11 12 public static void main(String[] args) {13 List pl = Person.createShortList();14 15 SearchCriteria search = SearchCriteria.getInstance();16 17 // Calc average age of pilots old style18 System.out.println("== Calc Old Style ==");19 int sum = 0;20 int count = 0;21 22 for (Person p:pl){23 if (p.getAge() >= 23 && p.getAge() p.getAge())40 .sum();41 42 // Get average of ages43 OptionalDouble averageAge = pl44 .parallelStream()45 .filter(search.getCriteria("allPilots"))46 .mapToDouble(p -> p.getAge())47 .average();48 49 System.out.println("Total Ages: " + totalAge);50 System.out.println("Average Age: " + averageAge.getAsDouble()); 51 52 }53 54 }

    Andtheoutputfromtheclassis:

  • == Calc Old Style ==Total Ages: 150Average Age: 37

    == Calc New Style ==Total Ages: 150Average Age: 37.5

    Theprogramcalculatestheaverageageofpilotsinourlist.Thefirstloopdemonstratestheoldstyleofcalculatingthenumberbyusingaforloop.Thesecondloopusesthemapmethodtogettheageofeachpersoninaserialstream.NoticethattotalAgeisalong.ThemapmethodreturnsanIntSteamobject,whichcontainsasummethodthatreturnsalong.

    Note:Tocomputetheaveragethesecondtime,calculatingthesumofagesisunnecessary.However,itisinstructivetoshowanexamplewiththesummethod.

    Thelastloopcomputestheaverageagefromthestream.NoticethattheparallelStreammethodisusedtogetaparallelstreamsothatthevaluescanbecomputedconcurrently.Thereturntypeisabitdifferenthereaswell.

    Resources

    TheNetBeansprojectwithsourcecodefortheexamplesisinthefollowingzipfile.

    LambdaCollectionExamples.zip

    Inthistutorial,youlearnedhowtouse:

    AnonymousinnerclassesinJava.LambdaexpressionstoreplaceanonymousinnerclassesinJavaSE8.Thecorrectsyntaxforlambdaexpressions.APredicateinterfacetoperformsearchesonalist.AFunctioninterfacetoprocessanobjectandproduceadifferenttypeofobject.NewfeaturesaddedtoCollectionsinJavaSE8thatsupportlambdaexpressions.

    Resources

    ForfurtherinformationonJavaSE8andlambdaexpressions,seethefollowing:

    Java8ProjectLambda

    Summary

    http://openjdk.java.net/projects/lambda/http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/examples/LambdaCollectionExamples.ziphttp://openjdk.java.net/projects/jdk8/
  • ProjectLambdaStateoftheLambdaStateoftheLambdaCollectionsJumpStartingLambdaJavaOne2012(YouTube)TolearnmoreaboutJavaandrelatedtopicscheckouttheOracleLearningLibrary.

    Credits

    LeadCurriculumDeveloper:MichaelWilliamsQA:JuanQuesadaNunez

    http://www.youtube.com/watch?v=bzO5GSujdqIhttp://www.oracle.com/goto/ollhttp://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-4.htmlhttp://openjdk.java.net/projects/lambda/http://cr.openjdk.java.net/~briangoetz/lambda/sotc3.html