概念:
Lambda表达式:特殊的匿名内部类,语法更简洁。
Lambda表达式允许把函数作为一个方法的参数(函数作为方法参数传递),将代码像数据一样传输
语法:
基本语法
<函数式接口><变量名>=(参数1,参数2)->{
//方法体;
}
函数时接口:接口中只有一个抽象方法
(参数1,参数2):抽象方法的参数
->:分割符
{}:抽象方法的实现
package com.lzl.test02;
public class Test01 {
public static void main(String[] args) {
My task = new My();
Thread t1 = new Thread(task);
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("这是匿名内部类方式的任务对象");
}
});
t2.start();
Thread t3 = new Thread(()->{
System.out.println("这是使用Lambda表达式完成的");
});
t3.start();
}
}
class My implements Runnable{
@Override
public void run() {
System.out.println("自定义任务接口类");
}
}
无参无返回值
package com.lzl.test02;
public class Test02 {
public static void main(String[] args) {
Swimmable swimmable = new Swimmable() {
@Override
public void swimming() {
System.out.println("这是使用内部匿名类的方式");
}
};
fun(swimmable);
Swimmable swimmable1 =()->{
System.out.println("这是使用Lambda表达式");
};
fun(swimmable1);
fun(()->{
System.out.println("这是简易模式的Lambda表达式");
});
}
public static void fun(Swimmable w){
w.swimming();
}
}
interface Swimmable{
public void swimming();
}
有参有返回值
package com.lzl.test03;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Test01 {
public static void main(String[] args) {
List list =new ArrayList<>();
list.add(new Peoson("张三",19));
list.add(new Peoson("李四",18));
list.add(new Peoson("王五",20));
list.add(new Peoson("赵六",16));
//对集合中的元素进行排序 传统做法 Comparator: 排序规则接口
Comparator comparator =new Comparator() {
@Override
public int compare(Peoson o1, Peoson o2) {
return o1.getAge()-o2.getAge();
}
};
Collections.sort(list,comparator);
for (Peoson p:list) {
System.out.println(p);
}
System.out.println("========================lambda表达式=====================================");
Collections.sort(list,(o1, o2) ->{
return o2.getAge()-o1.getAge();
}
);
for (Peoson p:list) {
System.out.println(p);
}
}
}
class Peoson{
String name;
int age;
public Peoson() {
}
public Peoson(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Peoson{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
}
详细介绍lambda表达式
函数式接口Lambda引入了新的操作符:->(箭头操作符)->将表达式分成两部分
左侧:(参数1,参数2.....)表示参数列
右侧:{ } 内部是方法体
注意事项
形参列表的数据类型会自动推断
如果形参列表为空,只需保留()
如果形参只有一个可以省略(),只需要参数名就可
如果执行语句只有一句,切无返回值,{ }可以省略,如有返回值 ,若想省去{ }则必须同时省略ruturn,切执语句也保证只有一句
Lambda不会生成一盒单独的内部类文件
如果一个接口只有一个抽象方法,则该接口称之为函数时接口,函数式接口可以使用Lambda表达式,lambda表达式会被分配到这个抽象方法
@Finctionallnterface 注解检测接口是否符合函数式接口
package com.lzl.test04;
public class Test01 {
public static void main(String[] args) {
Operater o =arr -> {
int sum =0;
for (int a:arr) {
sum += a;
}
System.out.println("数组的和为:"+sum);
};
fun(o);
}
public static void fun(Operater operater){
int[] arr = {2,3,5,7,8,9};
operater.getsum(arr);
}
}
interface Operater{
public abstract void getsum(int[] arr);
}
分析
我们知道使用Lambda表达式的前提是需要有函数式接口。而Lambda使用时不关心接口名,抽象方法名,只关心抽 象方法的参数列表和返回值类型。因此为了让我们使用Lambda方便,JDK提供了大量常用的函数式接口。
常见得函数式接口 Consumer有参数,无返回值。
package com.lzl.test05;
import java.util.function.Consumer;
public class Test01 {
public static void main(String[] args) {
Consumer consumer = money -> System.out.println("我去洗脚花了"+money+"元");
fun(consumer,2000);
}
public static void fun(Consumer consumer,double money){
consumer.accept(money);
}
}
Supplier无参,想有返回结果的函数式接口时,T表示返回值类型
package com.lzl.test06;
import java.util.Random;
import java.util.function.Supplier;
public class Test01 {
public static void main(String[] args) {
fun(()->{
return new Random().nextInt(10);
});
}
public static void fun(Supplier supplier){
Integer integer = supplier.get();
System.out.println("生成的内容为"+integer);
}
}
FunctionT: 参数类型的泛型
R: 函数返回结果的泛型
有参,有返回值
package com.lzl.test07;
import java.util.Locale;
import java.util.function.Function;
public class Test01 {
public static void main(String[] args) {
fun(msg->{return msg.toUpperCase();},"abcdefg");
}
public static void fun(Function function,String msg){
String apply = function.apply(msg);
System.out.println("转换后结果为:"+apply);
}
}
PredicatedT 参数类型
返回值为 boolean类型
package com.lzl.test07;
import java.util.function.Function;
import java.util.function.Predicate;
public class Test02 {
public static void main(String[] args) {
fun((msg)->{
return msg.length()>3?true:false;
},"王冰冰");
}
public static void fun(Predicate predicate,String msg){
boolean test = predicate.test(msg);
System.out.println("该名称的长度是否长:"+test);
}
方法引用
lambda表达式的冗余
package com.lzl;
import java.util.function.Consumer;
public class Test08 {
public static void main(String[] args) {
//如果我们在Lambda中所指定的功能,已经有其他方法存在相同方案,那是否还有必要再写重复逻辑?可以直接“引 用”过去就好了:---方法引用。
fun((arr->{
int sum=0;
for(int b:arr){
sum+=b;
}
System.out.println("数组的和为:"+sum);
}));
System.out.println("=============================方法应用后========================================");
//:: 这被成为方法引用,是一种新yufa
Consumer consumer = Test08::sum;
fun(consumer);
}
public static void fun(Consumer consumer){
Integer[] arr={1,2,3,4,5};
consumer.accept(arr);
}
public static void sum(Integer[] arr){
int sum = 0;
for (int i : arr) {
sum += i;
}
System.out.println("数组的和为:"+sum);
}
}
什么是方法引用
方法引用的分类 静态方法引用方法引用是lambda表达式的一种简写的方式。如果lambda表达式的方法体中只是调用一个特定的已经存在的方法,则可以使用方法引用
常见形式
对象::实例方法
类::静态方法
类::实例方法
类::new
静态方法引用,Lambda表达式要满足=(参数,..)->类名.静态方法(参数);可以简写为=类名::静态方法
public class Test01 {
public static void main(String[] args) {
List list=new ArrayList<>();
list.add(3);
list.add(7);
list.add(6);
list.add(9);
list.sort(Integer::compare);
System.out.println(list);
}
}
实例方法引用
实例方法引用,顾名思义就是调用已经存在的实例的方法,与静态方法引用不同的是类要先实例化,静态方法引用类无需实例化,直接用类名去调用。
实例方法引用,Lambda表达式要满足=(参数)->实例对象.实例方法(参数)
public class Test02 {
public static void main(String[] args) {
Peopel peopel = new Peopel("张三",20);
//实例方法的调用
fun(peopel::getName);
}
// 供给型--有参无返回值
public static void fun(Supplier supplier){
String peopel = supplier.get();
System.out.println(peopel);
}
}
class Peopel{
String name;
Integer age;
public Peopel() {
}
public Peopel(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Peopel{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
}
对象方法引用:
对象方法引用: 类名::实例方法. (参数1,参数2)->参数1.实例方法(参数2)
public class test01 {
public static void main(String[] args) {
Function function = s -> {
return s.length();
};
Integer hello = function.apply("hello");
System.out.println(hello);
//对象方法引用
Function function1 = String::length;
Integer word = function1.apply("word");
System.out.println(word);
//比较两个字符串的内容是否一致.T, U, R
// R apply(T t, U u);
BiFunction biFunction = String::equals;
Boolean apply = biFunction.apply("hello", "word");
System.out.println(apply);
}
}
构造方法引用:
构造方法引用: 类名::new (参数)->new 类名(参数)
public class test01 {
public static void main(String[] args) {
//构造方法引用
BiFunction biFunction1 = Peopel::new;
Peopel peopel = biFunction1.apply("张三", "20");
System.out.println(peopel);
}
}
class Peopel{
String name;
String age;
public Peopel() {
}
public Peopel(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
@Override
public String toString() {
return "Peopel{" +
"name='" + name + ''' +
", age='" + age + ''' +
'}';
}
public static void show(){
System.out.println("这是一个静态方法引用");
}
}



