可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表、函数主体、返回类型。这个定义还是太模糊的,让我们从以下几个关键词慢慢道来。
    ●匿名——我们说匿名,是因为它不像普通的方法那样有一个明确的名称:写得少而做得多!
    ●函数——我们说它是函数,是因为Lambda函数不像方法那样属于某个特定的类。但和方法一样,Lambda有参数列表、函数主体、返回类型。
    ●传递——Lambda表达式可以作为参数传递给方法或存储在变量中。
    ●简洁——无需像匿名类那样写很多模板代码。
    那到这里我们已经清楚了Lambda表达式的基本语法格式,那再继续思考一个问题:是不是所有的接口类型作为参数传递(传统写法就是匿名内部类)都可以使用Lambda表达式呢?
    答案是不可以!因为只有接口中只有一个抽象方法的时候,Lambda表达式才可以正确的“猜测”到你传递的任务实际上是在实现接口中的唯一的那一个抽象方法!
    那么我们把这种只有一个抽象方法的接口称作为“函数式接口”,只有函数式接口才可以使用Lambda表达式进行函数式编程!
    函数式接口-@FunctionalInterface
    只要确保接口中有且仅有一个抽象方法即可

    1. 修饰符 interface 接口名称 {
    2. [public abstract] 返回值类型 方法名称(可选参数信息);
    3. // 其他
    4. }
    5. 为了便于区分并便于编译器进行语法校验,JDK8中还引入了一个新的注解:
    6. @FunctionalInterface
    7. 该注解可用于一个接口的定义上,一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。
    8. 需要注意的是,即使不使用该注解,只要满足函数式接口的定义,该接口仍然是一个函数式接口,使用起来都一样。(可以类比下@Override 注解的作用)
    1. {
    2. //需求1 启动一个线程 输出Hello world
    3. //传统方式
    4. new Thread( new Runnable() {
    5. @Override
    6. public void run() {
    7. System.out.println( "hello world" );
    8. }
    9. } ).start();
    10. //函数式编程 Lambda
    11. new Thread(()-> System.out.println("hello world Lambda") ).start();
    12. //需求2筛选出大于100 的数据存放在list集合中
    13. //新建list集合
    14. List<Integer> list=new LinkedList<Integer>( );
    15. list.add( 1 );
    16. list.add( 101 );
    17. list.add( 1001 );
    18. list.add( 2 );
    19. //传统方法
    20. //新建list
    21. List<Integer>isOk=new LinkedList <>( );
    22. for (Integer o : list) {
    23. if(o>100){
    24. isOk.add( o );
    25. }
    26. }
    27. //lambdat方法使用strema流的方式
    28. isOk=list.stream().filter( e->e>100).collect( Collectors.toList());
    29. }
    30. //需求三:获取从低到高的排行前3的数据
    31. list.stream().sorted().limit( 3 ).collect( Collectors.toList() )
    32. .forEach( e -> {
    33. System.out.println( e );
    34. } );

    学习资料参考
    https://www.jianshu.com/p/d9b1c5d85d72