[Java Basic Grammar] Explain Java's Lambda Expressions in detail

1 Introduction

  • Lambda expressions are an important new feature in Java SE8
  • Lambda expressions allow you to replace functional interfaces with expressions
  • Lambda expressions, like methods, provide a normal parameter list and a body that uses those parameters
  • Lambda expression can be thought of as an anonymous function, named after the λ calculus in mathematics, it can also be called a closure
  • Lambda expressions allow a function to be used as a method parameter

2. Syntax of Lambda Expressions

Basic form: Lambda expression consists of three parts: parameter, -> symbol, method body

(参数列表)->{
    
    方法体}

Replenish:

  • Lambda expressions can have zero or more parameters
  • The type of the parameter can be explicitly declared or not, and it is implicitly inferred by the JVM. For example, (int a)and (a)have the same effect
  • When there is only one parameter and the type can be deduced, parentheses can be omitted, for example, (a)the same aeffect as
  • If the method body of the lambda expression has only one statement, the curly braces can be omitted
  • If the method body of the lambda expression has only one statement and is the return value, you can omit return

Code example:

// 不需要参数,返回值为 2
()->2
    
// 接收一个参数(数字类型),返回值为其2倍的值
x->2*x

// 接收两个参数(数字类型),并返回它们的和
(x,y)->x+y
    
// 接收两个 int 类型参数,返回它们的乘积
(int x,int y)->x*y

// 接收一个 String 对象,并在控制台打印
(String s)->System.out.println(s)

3. Function interface

ifAn interface has only one abstract method, and such an interface is called a single interface. Starting with JDK8, Java uses Lambda expressions and willA single interface is called a functional interface

Notice:

  • An interface is a functional interface if it has only one abstract method
  • If we declare an @FunctionInterfaceannotation , the compiler will require the interface according to the definition of the functional interface, so this interface can only have one abstract method. If it exceeds, the program will report an error when compiling

Sample code:

@functionInterface
interface A{
    
    
    void test();
}

4. The use of Lamdba expressions

Next, we will demonstrate the use of lambda expressions

// 无返回值无参数 
@FunctionalInterface interface NoParameterNoReturn {
    
     void test(); }
// 无返回值一个参数 
@FunctionalInterface interface OneParameterNoReturn {
    
     void test(int a); }
// 无返回值多个参数 
@FunctionalInterface interface MoreParameterNoReturn {
    
     void test(int a,int b); }
// 有返回值无参数 
@FunctionalInterface interface NoParameterReturn {
    
     int test(); }
// 有返回值一个参数 
@FunctionalInterface interface OneParameterReturn {
    
     int test(int a); }
// 有返回值多参数 
@FunctionalInterface interface MoreParameterReturn {
    
     int test(int a,int b); }

public class TestDemo {
    
     
    public static void main(String[] args) {
    
     
        NoParameterNoReturn noParameterNoReturn = ()->{
    
     System.out.println("无参数无返回值"); };
        noParameterNoReturn.test(); 
        
        OneParameterNoReturn oneParameterNoReturn = (int a)->{
    
     System.out.println("无参数一个返回值:"+ a); };
        oneParameterNoReturn.test(10); 
        
        MoreParameterNoReturn moreParameterNoReturn = (int a,int b)->{
    
     System.out.println("无返回值多个参数:"+a+" "+b); };
        moreParameterNoReturn.test(20,30); 
        
        NoParameterReturn noParameterReturn = ()->{
    
     System.out.println("有返回值无参数!"); return 40; };
        //接收函数的返回值 
        int ret = noParameterReturn.test(); 
        System.out.println(ret); 
        
        OneParameterReturn oneParameterReturn = (int a)->{
    
     System.out.println("有返回值有参数!"); return a; };
        ret = oneParameterReturn.test(50); 
        System.out.println(ret); 
        
        MoreParameterReturn moreParameterReturn = (int a,int b)->{
    
     System.out.println("有返回值多个参数!"); return a+b; };
        ret = moreParameterReturn.test(60,70);
		System.out.println(ret); 
    } 
}

5. Variable capture

5.1 Introduction

Variable capture exists for both local and anonymous classes in Java

Only after we understand what variable capture is, we can better understand the scope of lambda expressions, because lambda expressions also have variable capture.

5.2 Variable capture of anonymous inner classes

class A {
    
     
    public void func(){
    
     
        System.out.println("func()"); 
    } 
}
public class TestDemo {
    
     
    public static void main(String[] args) {
    
     
        int a = 100; 
        new Test(){
    
     
            @Override public void func() {
    
     
                System.out.println("我是内部类,且重写了func这个方法!");
                System.out.println("我是捕获到变量 a == "+a +" 我是一个常量,或者是一个没有改变过值的变量!"); 
            } 
        }; 
    } 
}

The variable a in the above code is a captured variable. This variable is either modified by final, or it is necessary to ensure that the variable is not modified when used in an anonymous inner class. If modified, a compilation error will occur.

5.3 Lambda variable capture

Variable capture is also possible in Lambda

@FunctionalInterface interface A {
    
     
    void test(); 
}
public static void main(String[] args) {
    
     
    int a = 10; 
    NoParameterNoReturn noParameterNoReturn = ()->{
    
    
        // a = 99; 如果修改a,则会报错 
        System.out.println("捕获变量:"+a); 
    };
    noParameterNoReturn.test(); 
}

6. The use of Lambda in collections

In order to make Lambda and Java collection classes work better together, some new interfaces have been added to the collection for docking with Lambda expressions

corresponding interface Added method
Collection removeIf()spliterator()stream()parallelStream()forEach()
List replaceAll()sort()
Map getDefault()forEach()replaceAll()putIfAbsent()remove()replace()computeIfAbsent()computeIfPresent()compute()merge()

Replenish:

Collection's forEach()methods are java.lang.Interableinherited from interface

6.1 Collection interface

Demonstration using the forEach() method

forEach()Source code: insert image description here

Code Example: Using Anonymous Inner Classes

public class TestDemo{
    
    
    public static void main(String[] args) {
    
    
        List<String> list=new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.forEach(new Consumer<String>() {
    
    
            @Override
            public void accept(String s) {
    
    
                System.out.print(s+" ");
            }
        });
    }
}
// 结果为:aaa bbb ccc

Code Example: Using Lambda

public class TestDemo{
    
    
    public static void main(String[] args) {
    
    
        List<String> list=new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.forEach(s -> System.out.print(s+" "));
    }
}
// 结果为:aaa bbb ccc

6.2 List interface

Demonstration using the sort() method

sort()Source code: insert image description here

Code Example: Using Anonymous Inner Classes

public class TestDemo{
    
    
    public static void main(String[] args) {
    
    
        List<String> list=new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.sort(new Comparator<String>() {
    
    
            @Override
            public int compare(String o1, String o2) {
    
    
                return o1.compareTo(o2);
            }
        });
        System.out.println(list);
    }
}
// 结果为:[aaa, bbb, ccc]

Code Example: Using Lambda

public class TestDemo{
    
    
    public static void main(String[] args) {
    
    
        List<String> list=new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.sort((String o1,String o2)->o1.compareTo(o2));
        System.out.println(list);
    }
}
// 结果为:[aaa, bbb, ccc]

6.3 Map interface

Demonstrate using the forEach() method of HashMap

HashMap 的 forEach()Source code:

insert image description here

Code Example: Using Anonymous Inner Classes

public class TestDemo{
    
    
    public static void main(String[] args) {
    
    
        Map<Integer,String> map=new HashMap<>();
        map.put(1,"aaa");
        map.put(2,"222");
        map.put(3,"333");
        map.forEach(new BiConsumer<Integer, String>() {
    
    
            @Override
            public void accept(Integer integer, String s) {
    
    
                System.out.println("Key="+integer+" Value="+s);
            }
        });
    }
}
/** 结果为:
Key=1 Value=aaa
Key=2 Value=222
Key=3 Value=333
*/

Code Example: Using Lambda

public class TestDemo{
    
    
    public static void main(String[] args) {
    
    
        Map<Integer,String> map=new HashMap<>();
        map.put(1,"aaa");
        map.put(2,"222");
        map.put(3,"333");
        map.forEach((Integer integer,String s)->
                System.out.println("Key="+integer+" Value="+s));
    }
}
/** 结果为:
Key=1 Value=aaa
Key=2 Value=222
Key=3 Value=333
*/

7. Advantages and Disadvantages of Lambda Expressions

advantage:

  • Simple code, rapid development
  • Convenient functional programming
  • Easy to parallelize
  • Java introduces Lambda to improve collection operations

shortcoming:

  • Poor code readability
  • In non-parallel computing, many computations may not have the high performance of traditional for loops

Guess you like

Origin blog.csdn.net/weixin_51367845/article/details/122031877