java Lambda 表达式

时间:2020-9-19 作者:admin

Java Lambda 表达式

Lambda 介绍

Lambda 表达式,也可称为闭包,他是推动 java8 发布的重要特征。
Lambda 允许把函数作为一个方法参数(函数作为参数传递进方法)。
使用 Lambda 表达式可以是代码更简洁紧凑。

基础语法

1. ( 参数 ) -> 方法体
2. ( 参数 ) -> { 方法体; };

重要特征

  • 可选类型声明: 不需要申明参数类型,编译器统一识别参数值
a -> a + 1; 
  • 可选的参数圆括号: 一个参数可以省略圆括号,但多个参数不能省略圆括号
a -> a + 1; //一个参数
(int a,int b) -> a - b; //多个参数
//根据可选类型声明,多个参数可以省略为
(a,b) -> a + b;
  • 可选的大括号: 如果方法体只有一个语句,可以省略大括号
a -> a+1;  
  • 可选的返回关键字: 如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
//接收一个String,直接在控制台输出,无返回值
(String s) -> System.out.print(s);
// 接收一个String,返回String
(String s) -> { return s; }

代码示例

package test;

public  class Test{
	public static void main(String args[]){
		Test tester = new Test();
		/**
		 *  定义具体计算
		 */
	      // 类型声明
	      MathOperation addition = (int a, int b) -> a + b;
	        
	      // 不用类型声明
	      MathOperation subtraction = (a, b) -> a - b;
	        
	      // 大括号中的返回语句
	      MathOperation multiplication = (int a, int b) -> { return a * b; };
	        
	      // 没有大括号及返回语句
	      MathOperation division = (int a, int b) -> a / b;
	        
	      System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
	      System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
	      System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
	      System.out.println("10 / 5 = " + tester.operate(10, 5, division));
	        
	      
	      // 不用括号
	      GreetingService greetService1 = message ->
	      System.out.println("Hello " + message);
	      greetService1.sayMessage("Runoob");
	        
	      // 用括号
	      GreetingService greetService2 = (message) ->
	      System.out.println("Hello " + message);
	      greetService2.sayMessage("Google");
	   }
	    
	   //数字计算
	   interface MathOperation {
	      int operation(int a, int b);
	   }
	   //接收数字,具体进行什么计算
	   private int operate(int a, int b, MathOperation mathOperation){
	      return mathOperation.operation(a, b);
	   }
	    
	   
	   interface GreetingService {
	      void sayMessage(String message);
	   }
	   
}

输出结果为:

10 + 5 = 15
10 - 5 = 5
10 x 5 = 50
10 / 5 = 2
Hello Runoob
Hello Google

注意

  • Lambda 表达是主要是用来定义行内执行的方法类型接口,例如,一个简单方法接口。
  • Lambda 表达式免去了使用匿名方法的麻烦。

变量作用域

Lambda 表达是只能应用 final 的局外变量,也就是不能再 lambda 内部修改定义在域外的局部变量,否则编译出错。
代码示例:

package csdnTest;

public class LambdaTest2 {
	final static int number_1=3;
	final static int number_2=2;
	
	public static void main(String[] args) {
		Num num = (a,b) -> a+b;
		
		System.out.println(num.addNum(number_1, number_2));
		//结果为5
	}
	
	interface Num{
		int addNum(int a,int b); 
	}
}

我们也可以在 lambda 表达式中访问外层变量

package csdnTest;

public class LambdaTest2 {
//	final static int number_1=3;
//	final static int number_2=2;
	
	public static void main(String[] args) {
		
		final int number_1=2;
		final int number_2=3;
		
		Num num = (a,b) -> a+b;
		
		System.out.println(num.addNum(number_1, number_2));
		//结果为5
	}
	
	interface Num{
		int addNum(int a,int b); 
	}
}

lambda 表达式的变量可以不用 final ,但是必须不可被后边的代码修改

package csdnTest;

public class LambdaTest2 {
	public static void main(String[] args) {
		
		int number_1=2;
		
		Num num = a ->number_1 = 5;//这里报错:Local variable number_1 defined in an enclosing scope must be final or effectively final
	
		System.out.println(num.addNum(number_1));
	}
	
	interface Num{
		int addNum(int a); 
	}
}

在 Lambda 表达式中不允许声明一个和变量同名的参数

package csdnTest;

public class LambdaTest2 {
	public static void main(String[] args) {
		
		int a=2;
		
		Num num = a ->a;//报错:Lambda expression's parameter a cannot redeclare another local variable defined in an enclosing scope. 
		
		System.out.println(num.addNum(a));
	}
	
	interface Num{
		int addNum(int a); 
	}
}

实例 forEach 遍历集合

实例对像

package csdnTest;

public class LambdaPerson {	
	private String name;
	private String sex;
	private int age;
}

forEach 遍历

package csdnTest;

import java.util.ArrayList;
import java.util.List;

public class LambdaTest2{
	public static void main(String[] args) {
		List<LambdaPerson> list = getPersonList();
        list.forEach(LambdaPerson -> System.out.println(LambdaPerson.toString()));
	}
	private static List<LambdaPerson> getPersonList(){
		LambdaPerson p1 = new LambdaPerson("张三","男",22);
		LambdaPerson p2 = new LambdaPerson("李四","男",21);
		LambdaPerson p3 = new LambdaPerson("赵丽","女",21);
		LambdaPerson p4 = new LambdaPerson("王五","男",21);
        List<LambdaPerson> list = new ArrayList<LambdaPerson>();
        list.add(p1);
        list.add(p2);
        list.add(p3);
        list.add(p4);
        return list;
    }
}
//结果为
LambdaPerson [name=张三, sex=男, age=22]
LambdaPerson [name=李四, sex=男, age=21]
LambdaPerson [name=赵丽, sex=女, age=21]
LambdaPerson [name=王五, sex=男, age=21]

使用Lambda表达式代替匿名内部类

	//匿名内部类
	public void runable() {
		new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类进入线程");
            }
        }).start();
	}
	//Lambda表达式
	public void runable() {
		 new Thread(() -> System.out.println("lambda进入线程")).start();
	}
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。