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

Top Related