JDK8新特性——Lambda表达式

Lambda表达式不是Java最早使用的,很多语言就支持Lambda表达式,例如:C++,C#,Python,Scala等。如果有Python或者Javascript的语言基础,对理解Lambda表达式有很大帮助,可以这么说lambda表达式其实就是实现SAM接口的语法糖,使得Java也算是支持函数式编程的语言。Lambda写的好可以极大的减少代码冗余,同时可读性也好过冗长的匿名内部类。

1、Lambda表达式引入

示例1:Runnable实现线程

public void test1(){
   		
	new Thread(new Runnable(){
   			
		public void run(){
   				
			System.out.println("do something..");			
		}		
	}).start();	
}

public void test2(){
   		
	new Thread(() -> System.out.println("do something..")).start();	
}

示例2:foreach遍历

public void test3(){
   
    List<String> list = Arrays.asList("hello","java","bdit","lambda");
    for (String string : list) {
   
        System.out.println(string);
    }
}

public void test4(){
   
    List<String> list = Arrays.asList("hello","java","bdit","lambda");
    list.forEach(System.out::println);
}

示例3:FileFilter文件过滤

public void test5(){
   
    //1.文件目录
    File fileDir=new File("D:/resource");
    //2.创建筛选规则,帅选出所有.java文件
    FileFilter filter=new FileFilter() {
   
        @Override
        public boolean accept(File file) {
   
            if(!file.isDirectory()&&file.getName().endsWith(".java")){
   
                return true;
            }
            return false;
        }
    };
    //3.得到筛选文件
    File[] files=fileDir.listFiles(filter);
    for (File file : files) {
   
        System.out.println(file);
    }
}

public void test6(){
   
    //1.文件目录
    File fileDir=new File("D:/resource");
    //2.得到筛选文件,帅选出所有.java文件
    File[] files=fileDir.listFiles((file) ->  !file.isDirectory() && file.getName().endsWith(".java"));
    //3、遍历查看结果
    Arrays.asList(files).forEach(System.out::println);
}

2、函数式接口概念

Lambda表达式是用来实现SAM接口的,所谓SAM接口就是Single Abstract Method,即该接口中只有一个抽象方法需要实现,当然该接口可以包含其他非抽象方法。

其实只要满足“SAM”特征的接口都可以称为函数式接口,但是如果要更明确一点,最好在声明接口时,加上@FunctionalInterface。

JDK1.8之前,核心类库中就已经存在很多SAM接口了,例如:
(1)java.lang.Runnable
(2)java.util.concurrent.Callable
(3)java.util.Comparator
(4)java.lang.Comparable
(5)java.lang.Iterable
(6)java.io.FileFilter
(7)java.lang.reflect.InvocationHandler
…等

但是在JDK1.8,只有(1)(2)(3)(6)加了@FunctionalInterface,那些没有加@FunctionalInterface的SAM接口,现在使用Lambda表达式实现,但是存在将来增加抽象方法变成非SAM接口的风险,因此建议只对加了@FunctionalInterface的接口使用Lambda表达式实现。

JDK1.8在java.util.function包增加了很多函数式接口,不过他们可以归纳为四类:消费型接口、供给型接口、功能型接口、判断型接口,一共43个,基本上可以满足开发中函数式接口的基本使用需求,如你在开发中需要设计函数式接口,请先从以下接口中选择是否有满足需求的,如果有几不需要重新设计了。

1、消费性接口

这类接口的抽象方法特点:有形参,但是返回值类型是void

接口名 抽象方法 描述
Consumer< T> void accept(T t) 接收一个对象用于完成功能
BiConsumer<T,U> void accept(T t, U u) 接收一个对象用于完成功能
DoubleConsumer void accept(double value) 接收一个double值
IntConsumer void accept(int value) 接收一个int值
LongConsumer void accept(long value) 接收一个long值
ObjDoubleConsumer< T> void accept(T t, double value) 接收一个对象和一个double值
ObjIntConsumer< T> void accept(T t, int value) 接收一个对象和一个int值
ObjLongConsumer< T> void accept(T t, long value) 接收一个对象和一个long值

2、供给型接口

这类接口的抽象方法特点:无参,但是有返回值

接口名 抽象方法 描述
Supplier< T> T get() 返回一个对象
BooleanSupplier boolean getAsBoolean() 返回一个boolean值
DoubleSupplier double getAsDouble() 返回一个double值
IntSupplier int getAsInt() 返回一个int值
LongSupplier long getAsLong() 返回一个long值

3、判断型接口

这里接口的抽象方法特点:有参,但是返回值类型是boolean结果。

接口名 抽象方法 描述
Predicate< T> boolean test(T t) 接收一个对象
BiPredicate<T,U> boolean test(T t, U u) 接收两个对象
DoublePredicate boolean test(double value) 接收一个double值
IntPredicate boolean test(int value) 接收一个int值
LongPredicate boolean test(long value) 接收一个long值

4、功能型接口

这类接口的抽象方法特点:既有参数又有返回值

接口名 抽象方法 描述
Function<T,R> R apply(T t) 接收一个T类型对象,返回一个R类型对象结果
UnaryOperator< T> T apply(T t) 接收一个T类型对象,返回一个T类型对象结果
DoubleFunction< R> R apply(double value) 接收一个double值,返回一个R类型对象
IntFunction< R> R apply(int value) 接收一个int值,返回一个R类型对象
LongFunction< R> R apply(long value) 接收一个long值,返回一个R类型对象
ToDoubleFunction< T> double applyAsDouble(T value) 接收一个T类型对象,返回一个double
ToIntFunction< T> int applyAsInt(T value) 接收一个T类型对象,返回一个int
ToLongFunction< T> long applyAsLong(T value) 接收一个T类型对象,返回一个long
DoubleToIntFunction int applyAsInt(double value) 接收一个double值,返回一个int结果
DoubleToLongFunction long applyAsLong(double value) 接收一个double值,返回一个long结果
IntToDoubleFunction double applyAsDouble(int value) 接收一个int值,返回一个double结果
IntToLongFunction long applyAsLong(int value) 接收一个int值,返回一个long结果
LongToDoubleFunction double applyAsDouble(long value) 接收一个long值,返回一个double结果
LongToIntFunction int applyAsInt(long value) 接收一个long值,返回一个int结果
DoubleUnaryOperator double applyAsDouble(double operand) 接收一个double值,返回一个double
IntUnaryOperator int applyAsInt(int operand) 接收一个int值,返回一个int结果
LongUnaryOperator long applyAsLong(long operand) 接收一个long值,返回一个long结果
BiFunction<T,U,R> R apply(T t, U u) 接收一个T类型和一个U类型对象,返回一个R类型对象结果
BinaryOperator< T> T apply(T t, T u) 接收两个T类型对象,返回一个T类型对象结果
ToDoubleBiFunction<T,U> double applyAsDouble(T t, U u) 接收一个T类型和一个U类型对象,返回一个double
ToIntBiFunction<T,U> int applyAsInt(T t, U u) 接收一个T类型和一个U类型对象,返回一个int
ToLongBiFunction<T,U> long applyAsLong(T t, U u) 接收一个T类型和一个U类型对象,返回一个long
DoubleBinaryOperator double applyAsDouble(double left, double right) 接收两个double值,返回一个double结果
IntBinaryOperator int applyAsInt(int left, int right) 接收两个int值,返回一个int结果
LongBinaryOperator long applyAsLong(long left, long right) 接收两个long值,返回一个long结果

3、Lambda表达式

Lambda表达式是用来实现SAM接口的,它相当于一个匿名函数,语法格式如下:

(Type1 param1, Type2 param2, ..., TypeN paramN) -> {
   
  statment1;  
  statment2;  
  //.............  
  return statmentM;
  }

简单的说就是:

(形参列表) -> {
   Lambda体}

这个操作符为 “->” , 该操作符被称为 Lambda 操作符或箭头操作符。它将 Lambda 分为两个部分:
(1)左侧:指定了 Lambda 表达式需要的参数列表,它其实就是函数式接口的抽象方法的形参列表
(2)右侧:指定了 Lambda 体,即 Lambda 表达式要执行的功能,它其实就是实现函数式接口的抽象方法的方法体。

例如:Lambda表达式只写了Runnable接口的抽象方法public void run()的()空参列表以及对run()方法的实现代码。

public void test1(){
   
    new Thread(new Runnable(){
   
        public void run(){
   
            System.out.println("do something..");
        }
    }
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值