Lambda expressions

1. Introduction to Lambda Expression

What is a Lambda?

Lambda is a new feature added to Java 8. To put it bluntly, Lambda is an anonymous function

Why use Lambda

Lambda expressions allow for a very concise implementation of an interface’s methods

Lambda’s requirements for interfaces

Although some interfaces can be simply implemented using Lambda expressions, not all interfaces can be implemented using Lambda expressions, and only one abstract method is required to be defined in an interface that must be implemented

In Java 8, a new feature has been added for interfaces: Default can modify interface methods using default, and the modified methods can be implemented by default in the interface

@FunctionalInterface

Pertaining to a functional interface in which there is only one abstract method

2. Basic syntax of Lambda

1. Grammar

// Lambda is an anonymous function that is generally concerned with the following two points // argument list method body /**

  • () : Used to describe the parameter list
  • {} : Used to describe method bodies can sometimes be omitted
  • ->: The Lambda operator is pronounced as goes to
  • Example Test t = () – > {System. Out. Println (” hello word “)}; Braces may be omitted

* /

2. Create multiple interfaces

/ * *

  • No parameter no return value interface
  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 10:24

*/ @FunctionalInterface public interface LambdaNoneReturnNoneParmeter { void test(); } / * *

  • No return value has a single parameter
  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 10:26

*/ @FunctionalInterface public interface LambdaNoneReturnSingleParmeter { void test(int n); } / * *

  • Interface with multiple parameters without a return value
  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 10:27

*/ @FunctionalInterface public interface LambdaNoneReturnMutipleParmeter { void test(int a,int b); } / * *

  • Interface with return value and no arguments
  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 10:28

*/ @FunctionalInterface public interface LambdaSingleReturnNoneParmeter { int test(); } / * *

  • An interface with a return value and a single parameter
  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 10:29

*/ @FunctionalInterface public interface LambdaSingleReturnSingleParmeter { int test(int n); } / * *

  • An interface with a return value and multiple parameters
  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 10:30

*/

@FunctionalInterface

public interface LambdaSingleReturnMutipleParmeter {



int test(int a,int b);

}

3. Create a test class

package com.alan.learn.syntax; import com.alan.learn.interfaces.*; / * *

  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 10:33

*/

public class Syntax1 {



public static void main(String[] args) {

// 1.Lambda表达式的基础语法

// Lambda是一个匿名函数 一般关注的是以下两个重点

// 参数列表 方法体



/**

  • () : Used to describe the parameter list
  • {} : Used to describe the method body
  • ->: The Lambda operator is pronounced as goes to

* / / / no and no return LambdaNoneReturnNoneParmeter lambda1 = () – > {System. Out. Println (” hello word “); }; lambda1.test(); / / there is no return value A single parameter LambdaNoneReturnSingleParmeter lambda2 = (int n) – > {System. Out. Println (” argument is: “+ n); }; lambda2.test(10); / / there is no return value Multiple parameters LambdaNoneReturnMutipleParmeter lambda3 = (int a, int b) – > {System. Out. Println (” parameters and is: “+ (a + b)); }; Lambda3. Test (10, 12); / / returns a value No parameter LambdaSingleReturnNoneParmeter lambda4 = () – > {System. Out. Println (” lambda4: “); return 100; }; int ret=lambda4.test(); System.out.println(” return value is: “+ret); / / returns a value A single parameter LambdaSingleReturnSingleParmeter lambda5 = (int a) – > {return a * 2; }; int ret2= lambda5.test(3); System.out.println(” Single argument, lambda5 returns :”+ret2); / / returns a value of multiple parameter LambdaSingleReturnMutipleParmeter lambda6 = (int a, int b) – > {return a + b; }; Int ret3 = lambda6. Test (12, 14); System.out.println(” Multiple arguments, lambda6 returns: “+ret3); }} output result: hello word argument is: 10 argument sum is: 22 lambda4: return value is: 100 single argument, lambda5 return value is :6 multiple arguments, lambda6 return value is: 26

Third, simplify the grammar

A simplification of the above basic syntax

1. Simplified parameter types

/ * *

  • Grammar to streamline
  • 1. Parameter types
  • Since the quantitative type of the parameter is already defined in the abstract method of the interface, the type of the parameter can be omitted in a Lambda expression
  • Note: if you need to omit the type, you should omit the type of each parameter. Never omit each one at all

*/ LambdaNoneReturnMutipleParmeter lambda1=(int a,int b)-> { System.out.println(“hello world”); }; Can reduce to: LambdaNoneReturnMutipleParmeter lambda1 = (a, b) – > {System. Out. Println (” hello world “); };

2. Simplify the braces of parameters

/ * *

  • 2. Parameter braces
  • If the number of arguments in the argument list is only one, you can omit the parentheses

*/ LambdaNoneReturnSingleParmeter lambda2=(a)->{ System.out.println(“hello world”); }; Can reduce to: LambdaNoneReturnSingleParmeter lambda2 = a – > {System. Out. Println (” hello world “); };

3. Simplification of braces

/ * *

  • 3. Method braces
  • If there is only one statement in the body of the method, the braces can be omitted

*/ LambdaNoneReturnSingleParmeter lambda3=a->{ System.out.println(“hello world”); }; Can reduce to: LambdaNoneReturnSingleParmeter lambda3 = a – > System. Out. The println (” hello world “);

4. Concise and supplement curly braces

/ * *

  • 4. If the only statement in the method body is a return statement
  • The thief must omit the return when omitting the braces

*/ LambdaSingleReturnNoneParmeter lambda4=()->{ return 10; }; Can reduce to: LambdaSingleReturnNoneParmeter lambda4 = () – > 10;

5. Multiple parameters, with a return value to simplify

LambdaSingleReturnNoneParmeter lambda4=(a,b)->{

return a+b;

}; Can reduce to: LambdaSingleReturnMutipleParmeter lambda5 = (a, b) – > a + b;

IV. Lambda syntax advanced

1. Method references (normal vs. static)

In practice, an interface will call the same implementation in many places, for example:

LambdaSingleReturnMutipleParmeter lambda1=(a,b)->a+b;

LambdaSingleReturnMutipleParmeter lambda2=(a,b)->a+b;

Each time you write down the specific implementation method A + B, and if the requirements change, each implementation needs to be changed. In this case, you can change the subsequent implementation to the defined method and call it directly as needed

Grammar:

/** * method reference:

  • It is possible to quickly point the implementation of a Lambda expression to an already implemented method
  • The member of a method is a class if it’s a static method and otherwise it’s a class object
  • The subordination of a method :: method name
  • Note:
  • 1. The number and type of parameters in the referenced method must be the same as the method defined in the interface
  • 2. The type of the return value must also be the same as the method in the interface

* /

Ex. :

  • package com.alan.learn.syntax;

    import com.alan.learn.interfaces.LambdaSingleReturnSingleParmeter;

    / * *

    • @author Alan
    • @ version 1.0
    • @date 2020-05-27 11:48
*/ public class Syntax3 { public static void main(String[] args) { LambdaSingleReturnSingleParmeter lambda1=a->a*2; LambdaSingleReturnSingleParmeter lambda2=a->a*2; LambdaSingleReturnSingleParmeter lambda3=a->a*2; / / simplified LambdaSingleReturnSingleParmeter lambda4 = a - > change (a); / / method references LambdaSingleReturnSingleParmeter lambda5 = Syntax3: : change; Private static int change(int a){return a*2; private static int change(int a){return a*2; }}

2. Method References (Constructors)

There is currently an entity class

public class Person {

public String name; public int age; Public Person() {System.out.println("Person's no-argument constructor execution "); } public Person(String name, int age) { this.name = name; this.age = age; System.out.println("Person's argument constructor execution "); }

}

demand

Two interfaces, each with a method, one of which requires a reference to the argumentless construction of Person, and one of which requires a reference to the argumentless construction of Person in order to return two Person objects, for example:

interface PersonCreater{

// Implements Person getPerson() using Person without arguments;

}

interface PersonCreater2{

Person getPerson(String name,int age);

}

Then you could write:

public class Syntax4 {

public static void main(String[] args) { PersonCreater creater=()->new Person(); PersonCreater Creater1 =Person::new; PersonCreater1 =Person::new; PersonCreater1 =Person::new; PersonCreater1 =Person::new; // This is equivalent to ()->new Person() // This is equivalent to rewriting getPerson() from the interface as new Person(). Person a=creater1.getPerson(); PersonCreate2 Create2 =Person::new; PersonCreate2 =Person::new; PersonCreate2 =Person::new; Person b=creater2.getPerson(" Person ",18); }

}

Note: Whether to refer to an argumentless construct or an argumented-construct depends on the method parameters defined by the interface

Five, comprehensive practice

1. Set sort cases

package com.alan.exercise;

import com.alan.learn.data.Person;

import java.util.ArrayList;

/ * *

  • Set sort case
  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 15:08

*/

public class Exercise1 {

Public static void main(String[] args) { ArrayList<Person bb0 list=new ArrayList<>(); ArrayList<Person bb0 list=new ArrayList<>(); ArrayList<Person bb0 list=new ArrayList<>(); ArrayList<Person bb0 list=new ArrayList<>(); List.add (new Person(" Person ",10)); List. Add (new Person(" Person ",12)); List. Add (new Person(" Person ",13)); List. Add (new Person(" Person ",14)); List. add(new Person(" lilei ",11)); List. Add (new Person(" Person ",8)); list.add(new Person("jack",10)); System.out.println(" before sort: "+list); //sort sorts the list using the provided Comparator to compare the elements. list.sort((o1, o2) -> o2.age-o1.age); System.out.println(" after sorting: "+list); }

}

2.Treeset sorting case

package com.alan.exercise;

import com.alan.learn.data.Person;

import java.util.TreeSet;

/ * *

  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 15:37

*/

public class Exercise2 {

Public static void main(String[] args) {/** TreeSet (String[] args) {/** TreeSet (String[] args); * Implement the Comparator interface using a Lambda expression and instantiate a TreeSet object * Note: * TreeSet<Person> set=new TreeSet<>((o1, o2) -> o2. Age -o1.age); * TreeSet<Person> set=new TreeSet<>((o1, o2) -> o2. Age -o1.age); */ TreeSet<Person> set=new TreeSet<>((o1, o2) ->{if(o1. Age >=o2. Age){return -1; }else { return 1; }}); Set. add(new Person(" Person ",10)); Set. add(new Person(" Person ",12)); Set. add(new Person(" Person ",13)); Set. add(new Person(" Person ",14)); Set. add(new Person(" Li Lei ",11)); Set. add(new Person(" Han Meimei ",8)); set.add(new Person("jack",10)); System.out.println(set); }

}

3. Set traversal

package com.alan.exercise;

import java.util.ArrayList;

import java.util.Collections;

/ * *

  • The traversal of the set
  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 15:52

*/

public class Exercise3 {

public static void main(String[] args) { ArrayList<Integer> list=new ArrayList<>(); Collections. AddAll (list, 1,2,3,4,5,6,7,8,9); /** * list.forEach(Consumer<? Super E> Action) * API documentation: Perform the given action on each element in the collection until all elements are processed or the action raises an exception. * will each element of the set into the interface method of Consumer accept Then method accept refer to our reference output * * a list of all elements of the set. The forEach (System. Out: : println); List.foreach (ele->{if(ele%2==0){System.out.println(ele); }}); }

}

4. Delete the elements in the collection that meet the criteria

package com.alan.exercise;

import com.alan.learn.data.Person;

import java.util.ArrayList;

/ * *

  • Deletes the element in the collection that meets the condition
  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 16:05

*/

public class Exercise4 {

public static void main(String[] args) { ArrayList<Person> list=new ArrayList<>(); List.add (new Person(" Person ",10)); List. Add (new Person(" Person ",12)); List. Add (new Person(" Person ",13)); List. Add (new Person(" Person ",14)); List. add(new Person(" lilei ",11)); List. Add (new Person(" Person ",8)); list.add(new Person("jack",10)); / / remove older than 12 element in the set/iterator practice before * * * * a ListIterator < Person > it = list. A ListIterator (); * while (it.hasNext()){ * Person ele=it.next(); * if(ele.age>12){ * it.remove(); *} *} */ /** * lambda implementation ** logic ** puts each element in the collection into the test method of the Predicate interface. * If the return value is true, */ list.removeIf(ele->ele.age>10); System.out.println(list); }

}

5. Create a thread to output a number

package com.alan.exercise;

/ * *

  • Requirements:
  • Open up a thread to do a numerical output
  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 16:17

*/

public class Exercise5 {

Public static void main(String[] args) {/** * Thread t=new Thread(()->{for(int I =0; i<100; i++){ System.out.println(i); }}); t.start(); }

}

VI. Function interface built into the system

package com.alan.functional;

import java.util.function.*;

/ * *

  • Some functional interfaces built into the system
  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 16:23

*/

public class FunctionalInterface {

Public static void main(String[] args) {// Predicate<T> : The parameter is T return value Boolean // In a subsequent if an interface needs to specify a type of parameter, If you return a Boolean, you can point to the Predicate // IntPredicate int -> Boolean // LongPredicate long-> Boolean // DoublePredicate double-> boolean // Consumer<T> : // LongConsumer long ->void // DoubleConsumer double ->void // Function<T,R> : R // LongFunction<R> long -> R // DoubleFunction<R> double -> R // IntToLongFunction int -> long // IntToDoubleFunction int -> double // LongToIntFunction long -> int // LongToDoubleFunction long -> double // DoubleToLongFunction double -> long // DoubleToIntFunction double -> int // (Supplier<T> : parameter T // UnaryOperator<T> : parameter T // BiFunction<T,U,R> :) Boolean // BiConsumer<T,U> : // BiConsumer<T,U> : Boolean // BiConsumer<T,U> : Predicate<T>, Consumer<T>, Function<T,R>, Supplier<T> */}

}

Lambda closures

package com.alan.closure;

import java.util.function.Supplier;

/ * *

  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 16:59

*/

public class ClosureDemo {

Public static void main(String[] args) {/** * Lambda's closure increases the life cycle of the enclose variable * So the local variable num is referenced by get() in the getNumber() method * int n=getNumber().get(); * int n=getNumber().get(); System.out.println(n); } private static Supplier<Integer> getNumber(){ int num=10; /** * Supplier supplier=()->num; * return supplier; */ return ()->{ return num; }; }

}


package com.alan.closure;

import java.util.function.Consumer;

/ * *

  • @author Alan
  • @ version 1.0
  • @date 2020-05-27 17:20

*/

public class ClosureDemo2 {

public static void main(String[] args) { int a=10; Consumer<Integer> c=ele->{ System.out.println(a+1); //System.out.println(ele); //System.out.println(a++); // Referring to a local variable in a lambda. This variable must be a constant}; //a++; 10 c.acept (1); 10 c.acept (1); 10 c.acept (1); }

}