java学习日记 Lambda表达式

Lambda表达式

冗余的Runnable代码

函数式编程

面对对象的思想

做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成这个事情

函数式编程的思想

只要获取到结果,谁去做的,怎么做的都不重要,重视结果不重视过程。

代码实现

package project;
/*
 * 使用Runnable接口的方式实现多线程程序
 */


public class test{
	public static void main(String[] args) {
		//创建Runnable接口的实现类对象
		test01 t1=new test01();
		//创建thread对象 构造方法中传递Runnable接口的实现类
		Thread t=new Thread(t1);
		//调用start方法开启新线程 执行run方法
		t.start();
		
		//简化代码 使用匿名内部类 实现多线程程序
		Runnable r=new Runnable() {
			
			@Override
			public void run() {
				System.out.println(Thread.currentThread().getName()+"新的线程创建了");
				
			}
		};
		new Thread(r).start();
		
		//再简化代码
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				System.out.println(Thread.currentThread().getName()+"新的线程创建了");
				
			}
		}).start();
	}
}

test01类:

package project;
/*
 *创建Runnable接口的实现类 重写run方法,设置线程任务
 */


public class test01 implements Runnable{
	@Override
	public void run() {
		
		System.out.println(Thread.currentThread().getName()+"新的线程创建了");
	}
}
代码分析

对于Runnable的匿名内部类用法 可以分析出

  • Thread类需要Runnable接口作为参数,其中的抽象方法run是用来指定线程任务内容的核心
  • 为了指定run的方法体 不得不需要Runnable接口的实现类
  • 为了省区定义一个Runnable实现类的麻烦 不得不使用匿名内部类
  • 必须覆盖重写抽象run方法 所以方法名称 方法参数 方法返回值不得不再写一遍 并且不能写错
  • 实际上 似乎只有方法体才是关键所在

编程思想的转换

做什么,而不是怎么做

我们不是真的想创建一个匿名内部类对象,我们只是为了做这件事情而不得不创建一个对象。我们真正希望做的事情是:将run方法体内的代码传递给Thread类知道

传递一段代码 这才是我们真正的目的 而创建对象只是限于面对对象语法而不得不采用的一种手段

如果将怎么做回归到做什么的本质上 就会发现只要能够更好的达到目的 过程和形式并不重要

Lambda的更优写法

代码

使用Lambda表达式实现上述Runnable匿名内部类的效果

package project;
/*
 * 使用Lambda表达式来实现优化
 */


public class test{
	public static void main(String[] args) {
		new Thread(()->System.out.println("多线程任务执行")).start();//启动线程
	}
}

。。。确实有点简单哦

语义分析

Runnable接口只有一个run方法的定义:

  • public void run();
    即制定了一种做事情的方案(一个函数):
  • 无参数:不需要任何条件就可以执行该方案
  • 无返回值:该方案不产生任何结果
  • 代码块(方法体):该方案的具体执行步骤

同样的予以体现在Lambda语法中 要更加简单

()->System.out.println("多线程任务执行")

  • 前面的一对小括号就是run方法的参数(无) 代表不需要任何田间
  • 中间的一个箭头代表将前面的参数传递给后面的代码
  • 后面的输出语句就是业务逻辑代码

标准格式

  • 一些参数
  • 一个箭头
  • 一段代码

Lambda标准格式
(参数类型 参数名称)->{ 代码语句 }

格式说明:

  • 小括号内的语法与传统方法参数列表一致:无参数留空; 多个参数则用逗号分隔
  • ->是新引入的语法形式, 代表指向动作
  • 大括号内的语法与传统方法体要求基本一致(需要执行的代码)
无参数无返回值代码练习

Cook接口:

package project;

public interface Cook {
	void makeFood();
}

main:

package project;
/*
 * Lambda标准格式
 * 	由三部分组成
 * 		a 一些参数
 * 		b 一个箭头
 * 		c 一段代码
 * 	格式:
 * 		(参数类型 参数名称)->{ 代码语句 }
 * 	解释说明格式:
 * 		小括号内的语法与传统方法参数列表一致:无参数留空; 多个参数则用逗号分隔
 * 		```->```是新引入的语法形式, 代表指向动作
 * 		大括号内的语法与传统方法体要求基本一致(需要执行的代码)
 * 
 * 	需求:
 * 		给定一个Cook厨子接口 内含唯一的抽象方法makeFood 且无参数 无返回值
 * 		使用Lambda表达式调用invokeCook方法 打印输出“吃饭了!”字样
 */



public class test{
	public static void main(String[] args) {
		//使用Lambda表达式调用invokeCook方法
		
		//匿名内部类
		invokeCook(new Cook() {
			@Override
			public void makeFood() {
				System.out.println("吃饭了!");
				
			}
		});
		
		//使用Lambda表达式
		invokeCook(()->
		{
			System.out.println("吃饭了!");
		}
		);
		
	}
	
	//定义了一个方法 参数传递了Cook接口 方法内部调用Cook接口中的方法makeFood
	private static void invokeCook(Cook cook) {
		cook.makeFood();
	}
}
有参数有返回值代码练习

Person类:

package project;

public class Person {
	private String name;
	private int age;
	
	public Person() {
		// TODO Auto-generated constructor stub
	}
	
	public Person(String name,int age){
		this.age = age;
		this.name = name;
	}
	
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "Person{"+
				"name='"+name+'\''+
				",age="+age+
				'}';
	}
	
	public String getName() {
		return name;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	public void setName(String name) {
		this.name = name;
	}
}

匿名内部类和Lambda表达式的对比

package project;
/*
 * Lambda表达式有参数有返回值的练习
 * 需求:
 * 		使用数组存储多个Person对象
 * 		对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序
 */

import java.util.Arrays;
import java.util.Comparator;

public class test{
	public static void main(String[] args) {
		//使用数组存储多个Person对象
		Person[] arr= {
				new Person("刘艳",18),
				new Person("张三",25),
				new Person("赵四",20),
		};
		
		//对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序
//		Arrays.sort(arr,new Comparator<Person>() {
//
//			@Override
//			public int compare(Person o1, Person o2) {
//				
//				return o1.getAge()-o2.getAge();
//			}
//		});
		
		//使用Lambda表达式 简化匿名内部类
		Arrays.sort(arr,(Person o1,Person o2)->{
			
				
				return o1.getAge()-o2.getAge();
			
		});
		
		
		//遍历数组
		for(Person p:arr) {
			System.out.println(p);
		}
	}
	
}

Lambda省略

省略规则

在Lambda标准格式的基础上,使用省略写法的规则为:

  1. 小括号内参数的类型可以省略;
  2. 如果小括号内有且仅有一个参,则小括号可以省略;
  3. 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号。
省略练习

非省略形式

Arrays.sort(arr,(Person o1,Person o2)->{	
				return o1.getAge()-o2.getAge();
		});

省略形式

Arrays.sort(arr,(o1,o2)->o1.getAge()-o2.getAge());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值