第十四章lambda表达式与流处理

Iambda表达式简介

  1. lambda表达式可以用非常少的代码实现抽象方法。
  2. lambda表达式不能独立执行,因此必须实现函数式接口,并且会返回一个函数式接口的对象。
  3. lambdab表达式的语法非常特殊

    语法格式:

    ()-> 结果表达式 

    参数-> 结果表达式

    (参数1,参数2...,参数n)-> 结果表达式

第1行实现无参方法,单独写一对圆括号表示方法无参数,操作符右侧的结果表达式表示方法的返回值。
第2行实现只有一个参数的方法,参数可以写在圆括号里,或者不写圆括号。
第3行实现多参数的方法,所有参数按顺序写在圆括号里,且圆括号不可以省略。
lambda表达式也可以实现复杂方法,将操作符右侧的结果表达式换成代码块即可


语法格式如下:
()->{代码块)
参数->(代码块}
(参数1,参数2,..参数n)->{代码块)

  • 第1行实现无参方法,方法体是操作符右侧代码块。
  • 第2行实现只有一个参数的方法,方法体是操作符右侧代码块。
  • 第3行实现多参数的方法,方法体是操作符右侧代码块。
  • lambda表达式的功能归纳总结,语法理解为:

    ()                       ->               {代码块}

    这个方法            按照              这样的代码来实现

Iambda表达式实现函数式接口

1.函数式接口

开发者可以常见自定义的函数式接口

例如:

interface MyInterface{

        void method();

}

 如果接口中包含一个以上的抽象方法,则不符合函数式接口的规范,这样的接口不能用Iambda表达式创建匿名对象

2.Iambda表达式实现无参数抽象方法

 

 
	interface SayHiInterface{	//例题14.1
		String say();//抽象方法接口
	}
 
 
public class NoParamterDemo {
	public static void main(String[] args) {//利用匿名内部类补全方法体
		//lambda表达式实现发招呼接口,返回抽象方法结果
		SayHiInterface pi=()->"你好啊,这是lanbda表达式";
		 System.out.print(pi.say());
	}
 
}

 

3.lambda表达式实现有参抽象方法

如果抽象方法中只有一个参数,lambda表达式则可以省略圆括号

例题14.2

interface AddInt{
	int add(int a,int b);
}
public class ParamDemo {
 
	public static void main(String[] args) {
		// TODO Auto-generated method stub
/*无参数      AddInt ai1 = new AddInt() {
			public int add(int a,int b) {
			return a+b;
		}
	};
	System.out.println("匿名内部类:" + ai1.add(3,5));
	//使用Lambda表示式补全方法体
	AddInt ai2 = (a, b) ->{
		return a+b;
	};
	System.out.println("lambda表达式:" + ai2.add(3,5));
}
}*/
	AddInt np=(x,y)->x+y;		//表达式
	int result=np.add(15,26);					//调用接口方法
	System.out.println("相加结果:"+result);			//输出相加结果
	}
}

 ambda表达式中的参数不需要与抽象方法的参数名称相同,但顺序必须相同

4.lambda表达式使用代码块

lambda表达式会自动判断返回值类型是否符合抽象方法的定义

例题14.3

interface CheckGrade{			//例题14.3
	String check(int grade);    //查询成绩结果
}
public class GradeDemo {
 
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		CheckGrade g =(n)-> {			//lambda表达式实现代码块
			if (n>=90&& n<=100) {		//如果成绩在90~100
				return"成绩为优";			//输出成绩为优
			}else if (n>=80&& n<=90) {	//如果成绩在80~90
				return"成绩为良";			//输出成绩为良
			}else if (n>=60&& n<=80) {	//如果成绩在60~80
				return"成绩为中";			//输出成绩为中
			}else if (n>=0&& n<=60) {	//如果成绩在00~60
				return"成绩为差";			//输出成绩为差
			}else {						//其他数字不是有效成绩
				return"成绩无效";			//输出成绩无效
	}
};
	System.out.println(g.check(89));
	}
}

Iambda表达式调用外部变量 

这些外部的变量有些可以被更改,有些则不能。例如,lambda表达式无法更改局部变量的值,但是却可以更改外部类的成员变量(也可以叫做类属性)的值他。

1.lambda表达式无法更改局部变量

局部变量在lambda表达式中默认被定义为final(静态)的,也就是说,lambda表达式只能调用局部变量,却不能改变其值。

例题14.4

interface VariableInterface1{		//例题14.4
	void method();
}
public class VariableDemo1 {
	
 
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int value=100;
		VariableInterface1 v=()->{
			int num=value-90;
			value=12;
		};
	}
 
}

 

2.lambda表达式可以更改类成员变量

类成员变量是在lambda表达式中不是被final修饰的,所以lambda表达式可以改变其值

例题14.5

interface VariableInterface2{					//测试接口
	void method();								//测试方法
}
 
public class VariableDemo2 {					//测试类
	int value = 100;							//创建类成员变量
	public void action() {						//创建类成员方法
		VariableInterface2 v=()->{				//实现测试接口
			value =-12;							//更改成员变量,没提示任何错误
		};
		System.out.println("运行接口方法前value="+value);  //运行接口方法前先输出成员变量值
		v.method();										 //运行接口方法
		System.out.println("运行接口方法后value="+value); //运行接口方法后再输出成员变量值
	}
	public static void main(String[] args) {
		VariableDemo2 demo = new VariableDemo2();	//创建测试类对象
		demo.action();								//执行测试类方法
	}
 
}

 

lambda 表达式可以调用并修改类成员变量的值
lambda表达式只是描述了抽象方法是如何实现的,在抽象方法没有被调用前,lambda表达式中的代码并没有被执行,所以运行抽象方法之前类成员变量的值不会发生变化。
只要抽象方法被调用,就会执行lambda 表达式中的代码,类成员变量的值就会被修改。
 

Iambda表达式与异常处理

lambda 表达式中并有抛出异常的语法,这是因为lambda表达式会默认抛出抽象方法原有的异常,当此方法被调用时则要进行异常处理。

例题14.6

import java.util.Scanner;											
interface AntiaddictInterface{											//防沉迷接口
	boolean check(int age)throws UnderAgeException;						//抽象检查方法,抛出用户未成年异常
}
 
class UnderAgeException extends Exception{								//自定义未成年异常
	public UnderAgeException(String message) {							//有参构造方法
		super(message);													//调用原有父类构造方法
	}
}
 
public class ThrowExceptionDemo {										//测试类
	public static void main(String[] args) {							//主方法
		//lambda表达式创建AntiaddictInterface对象,默认抛出原有异常
		AntiaddictInterface ai =(a)->{
			if(a<18) {													//如果年龄小于18岁
				throw new UnderAgeException("未满18周岁,开启防沉迷模式!");		//抛出异常
			}else {														//否则
				return true;											//验证通过
			}
		};
		
		Scanner sc = new Scanner(System.in);							//创建控制台扫描器
		System.out.print("请输入年龄:");									//控制台提示
		int age = sc.nextInt();											//获取用户输入的年龄
		
		try {															//因为接口方法抛出异常,所以此处必须捕捉异常
			if(ai.check(age)) {											//验证年龄
				System.out.println("欢迎进入XX世界");
			}
		}catch(UnderAgeException e) {									//控制台打印异常警告
			System.out.println(e);
		}
		sc.close();														//关闭扫描器
	}
}

 

 

14.2方法的引用

引用静态方法

语法:

类名::静态方法名 

 

新的操作符“::”,中间无空格,左边表示方法所属的类名,右边是方法名,语法中方法名是没有括号的。 

例题14.7

interface StaticMethodInterface{		//测试接口  例题14.7
	int method(int a, int b);			//抽象方法
}
public class StaticMethodDemo {
	static int add(int x,int y) {		//静态方法,返回两个参数相加的结果
		return x +y;					//返回相加结果
	}
 
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		StaticMethodInterface sm= StaticMethodDemo::add;	//引用StaticMethodDemo类的静态方法
		int result = sm.method(15,16);						//直接调用接口方法获取结果
		System.out.println("接口方法结果:"+result);				//输出结果
	}
 
}

 

 引用成员方法

引用成员方法的语法:

对象名::成员方法名

操作符左侧必须是一个对象名,而不是类名。 

例题14.8

import java.text.SimpleDateFormat;			//例题14.8
import java.util.Date;
interface InstanceMethodInterface{			//测试创建接口
	String method(Date date);				//带参数的抽象方法
}
public class InstanceMethodDemo {
	public String format(Date date) {		//格式化方法
		//创建日期格式化对象,并指定日期格式
		SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd");
		return sdf.format(date);			//返回格式化结果
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		InstanceMethodDemo demo = new InstanceMethodDemo();			//创建类对象
		InstanceMethodInterface im = demo::format;					//引用类对象的方法
		Date date = new Date();										//创建日期对象
		System.out.println("默认格式:"+date);							//输出日期对象默认格式
		System.out.println("接口输出的格式:"+im.method(date));			//输出经过接口方法处理过的格式
	}
 
}

 

 

引用带泛型的方法 (14.9/12/13不用写博客)

引用构造方法

Iambda表达式有3种引用构造方法的语法,分别是引用无参数构造方法、引用有参构造方法和引用数构造方法

1.引用无参构造方法

语法:

类名::new

注意:new关键字之后没有圆括号,也没有参数的定义 

interface ConstructorsInterface1{								//构造方法接口
	ConstructorsDemo1 action();									//调用无参方法
}
public class ConstructorsDemo1 {								//测试类
	public ConstructorsDemo1() {								//无参构造方法
		System.out.print("无参构造方法");
	}
	public ConstructorsDemo1(int a) {							//有参构造方法
		System.out.print("有参构造方法"+ a);
	}
	public static void main(String[] args) {				
		ConstructorsInterface1 ci = ConstructorsDemo1::new;		//引用ConstructorsDemo1类的构造方法
		ci.action();											//通过无参方法创建对象
 
	}
 
}

 

2.引用有参构造方法

引用有参构造方法的语法与引用无参构造方法一样。区别就是函数式接口的抽象方法是有参数的

例题14.11

interface ConstructorsInterface2{								//构造方法接口
	ConstructorsDemo2 action(int i);							//调用有参方法
}
public class ConstructorsDemo2 {								//测试类
	public ConstructorsDemo2(){									//无参构造方法	
		System.out.print("调用无参构造方法");
	}
	public ConstructorsDemo2(int i) {							//有参构造方法
		System.out.println("有参构造方法,参数为:"+i);
	}
	public static void main(String[] args) {					
		ConstructorsInterface2 a = ConstructorsDemo2::new;		//引用ConstructorsDemo1类的构造方法
		ConstructorsDemo2 b = a.action(123);					//通过无参方法创建对象
	}
 
}

 

.引用数组构造方法

 语法;

类名[]::new

 

14.2.5Fuction接口 

这个接口有以下两个泛型:

  1. T:被操作的类型,可以理解为方法参数类型。
  2. R:操作结果类型,可以理解为方法的返回类型。
  3. Function 接口是函数式接口,所以只有一个抽象方法,但是Function 接口还提供
    方法以方便开发者对函数逻辑进行更深层的处理。

 

14.3流处理

流处理有点类似数据库的 SQL 语句,可以执行非常复杂的过滤、映射、查找和收集功能,并且代码量很少。唯一的缺点是代码可读性不高。

对员工数据进行流处理

员工集合的详细数据如下

import java.util.ArrayList;
import java.util.List;
 
public class Employee {
	private String name;	//姓名
	private int age;		//年龄
	private double salary;	//工资
	private String sex;		//性别
	private String dept;	//部门
	
	public Employee(String name, int age, double salary, String sex, String dept) {
		super();
		this.name = name;
		this.age = age;
		this.salary = salary;
		this.sex = sex;
		this.dept = dept;
	}
	
	@Override
	public String toString() {
		return "Employee [name=" + name + ", age=" + age + ", salary=" + salary + ", sex=" + sex + ", dept=" + dept
				+ "]";
	}
 
	public String getName() {
		return name;
	}
 
	public int getAge() {
		return age;
	}
 
	public double getSalary() {
		return salary;
	}
 
	public String getSex() {
		return sex;
	}
 
	public String getDept() {
		return dept;
	}
	static List<Employee> getEmpList(){
		List<Employee> list=new ArrayList<Employee>();
		list.add(new Employee("老张",40,9000,"男","运营部"));
		list.add(new Employee("小刘",24,5000,"女","开发部"));
		list.add(new Employee("大刚",32,7500,"男","销售部"));
		list.add(new Employee("翠花",28,5500,"女","销售部"));
		list.add(new Employee("小马",21,3000,"男","开发部"));
		list.add(new Employee("老王",35,6000,"女","人事部"));
		list.add(new Employee("小王",21,3000,"女","人事部"));
		return list;
	}
}
 

 

方法如下:

Source——Generate ConStructor using Fields

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值