【JavaSE】Lambda表达式

1. 简单入门

1.1 概述

函数式接口:接口中仅且只有一个抽象方法,可用@FunctionalInterface注解标注接口,当多个抽象方法时会报错
Lambda:用于简化函数式接口抽象方法的实现,可替换匿名内部类的作用

1.2 入门例子

  1. 定义函数式接口
@FunctionalInterface  // 注解非必须,只要保证接口只有一个抽象方法即可
interface Calculator{
    int cal(int a,int b);
}
  1. 调用接口的抽象方法
public void invokeCal(int a,int b,Calculator calculator){
    int result= calculator.cal(a,b);
    System.out.println(result);
}
  1. 使用Lambda表达式简化抽象方法的实现
@Test
public void test(){
    invokeCal(1,2,(int a,int b)->{return a+b;});
    invokeCal(1,2,(int a,int b)->{return a-b;});
    invokeCal(1,2,(int a,int b)->{return a*b;});
    invokeCal(1,2,(int a,int b)->{return a/b;});
}

2. Lambda语法

2.1 语法说明

(形参列表) -> {Lambda体} (int a)->{return a*10;}

  • (形参列表)它就是你要赋值的函数式接口的抽象方法的(形参列表),照抄
  • {Lambda体}就是实现这个抽象方法的方法体
  • ->称为Lambda操作符(减号和大于号中间不能有空格,而且必须是英文状态下半角输入方式)

2.2 语法优化

  • (int a)->return a*10当{Lambda体}中只有一句语句时,可以省略{}和;
  • (int a)->a*10当{Lambda体}中只有一句语句时,并且这个语句还是一个return语句,那么return也可以省略,但是如果{;}没有省略的话,return是不能省略的
  • (a)->a*10(形参列表)的类型可以省略
  • a->a*10当(形参列表)的形参个数只有一个,那么可以把数据类型和()一起省略,但是形参名不能省略
  • 当(形参列表)是空参时,()不能省略

3. 四大内置函数式接口

3.1 消费型接口Consumer

Consumer:有参数,无返回值

Consumer接口源码

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

集合迭代接口Iterable应用了Consumer

public interface Iterable<T> {
	default void forEach(Consumer<? super T> action) 
}

测试

List<String> list= Arrays.asList("a","b","c");
// 参数l表示集合中每个元素
list.forEach(l-> System.out.println(l));

3.2 供给型接口Supplier

Supplier:无参,有返回值

Supplier接口源码

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

数据流Stream类应用了Supplier

// 返回一个新的无限顺序无序的流
public static Stream<T> generate(Supplier<T> s)

测试

// Supplier
Stream<Double> stream = Stream.generate(() -> Math.random());

// Consumer
stream.forEach(s-> System.out.println(s));

3.3 功能型接口Function

Function:有参数,有返回值

Function接口源码

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

Map集合应用了Function

// 如果Map中的key对应的value值为null,则调用Function
V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) 

测试

Map<String,List> map=new HashMap<>();
// Function
// 如果Map中key为hobby的value为null,则把value=new ArrayList()
List<String> list=map.computeIfAbsent("hobby",key->{return new ArrayList(); });
list.add("篮球");

// BiConsumer<? super K, ? super V>
map.forEach((k,v)->System.out.println(k+":"+v));

3.4 判断型接口Predicate

Predicate:有参数,返回值为布尔类型

Predicate接口源码

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

Collection集合应用了Predicate

// 满足条件则删除
public boolean removeIf(Predicate<? super E> filter) {

测试

List<Integer> list=new ArrayList<>();  // 不能用Arrays.asList
list.add(1);
list.add(2);
list.add(3);

// Predicate
list.removeIf(l->l<3);

list.forEach(l-> System.out.println(l));

4.Lambda引用简化

4.1 方法引用简化

前提

  • Lambda体只有一句语句,并且该语句是通过调用外部现有的类或对象的方法来完成的
  • 形参列表跟被调用类或对象的方法的形参列表一致;或者形参列表第一个形参被调用对象的方法的调用者,形参列表后面的形参仍需要跟被调用对象的方法的形参列表一致;

简化

  • 实际简化的是去掉lambda形参列表和调用方法的形参列表

语法

  • 实例对象名::实例方法
  • 类名::静态方法
  • 类名::实例方法

测试
形参列表一致

List<Integer> list = Arrays.asList(1,2,3);

// lambda参数列表t与System.out的方法println()参数列表一致,可简化
list.forEach(t -> System.out.println(t));

// 对象方法引用简化,去掉了lambda参数列表t和println的参数列表
list.forEach(System.out::println);

形参列表一个参数是方法调用者

// lambda形参第一个参数x是equals方法的调用者,lambda形参其他参数y跟equals方法参数一致
BiPredicate<String,String> bi=(x, y)->x.equals(y);

// 简化,这里要使用lambda形参第一个参数的类String
BiPredicate<String,String> bi2=String::equals;

排序

List<Integer> list= Arrays.asList(5,6,2,8,1,4);

// 方式1:手写比较规则
list.sort((a,b)->a.compareTo(b));

// 方式2:方法引用简写
list.sort(Integer::compareTo);

// 方式3:使用Comparator接口
list.sort(Comparator.comparingInt(a->a));

list.forEach(System.out::println);

4.2 构造器简化

跟方法引用简化基本一样

类构造器简化
lambda形参列表与类构造方法参数列表一致

 // lambda形参列表与File构造方法参数列表一致
 Function<String,File> f1=s->new File(s);
 // 简化
 Function<String,File> f2=File::new;

 File file = f2.apply("F:\\a.txt");
 System.out.println(file.getName());

数组构造器简化
lambda参数作为数组创建时的长度参数

// lambda参数作为数组创建时的长度参数
Function<Integer,int[]> f1=l->new int[l];
// 简化
Function<Integer,int[]> f2=int[]::new;
int[] arr = f2.apply(5);
System.out.println(arr.length);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值