Java lambda表达式语法及简单示例

前言

在JAVA SE 8 之前,在java中传递一个代码块并不容易,不能直接传递代码块,因为java是一种面向对象的语言,所以想传递代码块需要把所需传递的代码写在类的方法里,然后通过传递类的实例(即对象)才能达到传递代码块的目的。
为了解决这一问题,JAVA SE 8 加入lambda表达式这一新特性,可以用一种简洁的语法来定义代码块,并把这个代码块传递给某个对象,这个代码块可以在将来的某个时间被调用一次或者多次调用。

语法

lambda表达式的一般构成:参数, 箭头(->) 以及一个表达式
如果代码要完成的计算无法放在一个表达式中,就可以像写方法一样,把这些代码放在 {}里,还可以显式的使用return语句。
即:
(parameters) -> expression 或 (parameters) ->{ statements; }
实例:

//参数可以为空,但仍然需要提供括号
()-> System.out.println("haha");
//多行代码时需要用{}包裹,还可以使用return语句
(int x)->{ System.out.println(x);return x*x;}
//可以不指定的返回类型。返回类型总是会由上下文推导得出
(String first,String second)->first.length()-second.length();
//当参数类型可以通过上下文推导出来,参数类型可以省略
//比如下面,lambda表达式被赋值给一个字符串比较器,所以编译器可以推导出
//参数类型是String
Comparator<String> comp = (first,second)->first.length()-second.length();
//当参数只有一个,且类型可以由上下文推导而出的时候,小括号可以省略
ActionListener listener = event -> System.out.println("现在的时间为:"+new Date());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

函数式接口的编写

java已经提供了支持lambda表达式的接口,比如上面的ActionListener,Comparator,那么问题来了,接口符合什么要求就可以支持lambda表达式呢?
要求很简单:接口有且最多只能有一个抽象方法(ps:可以有其他默认方法,但抽象方法只能有一个,否则lambda表达式赋值的时候会因为无法确定是哪个抽象方法而报错)。
现在我们就试着自己编写一个函数式接口,并试着给他传入一个lambda表达式,看能不能正常接收。

public  interface Person{
    public void test(String s);
}
  • 1
  • 2
  • 3

好了,这样就写好了一个支持lambda表达式的函数式接口。现在是不是发现这个接口没有任何特殊之处,就像我们平时写的一些接口。(换句话说,你平时写的一些接口就支持lambda表达式)。
下面我们就编写一个lambda表达式传入test方法。

public class PersonTest {
    public static void main(String[] args){
        //向p对象中的test方法传入lambda表达式
        //下面两个表达式等价
        //因为参数只有一个,且参数类型可从test方法的定义推出
        //所以可以省略小括号和参数类型
        Person p = s -> System.out.println(s);
        //Person p = (String s)-> System.out.println(s);

        //调用p对象的test方法时,会执行刚刚传入的lambda表达式
        p.test("lambda表达式测试");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

执行结果如下:
在这里插入图片描述
重新写下Person接口再测试一下

public  interface Person{
    //把刚刚的抽象方法改成默认方法
    public default void test(String s){
        System.out.println("这是接口的默认方法,传入的字符串为:"+s);
    };
    //重新定义一个有返回值抽象的方法
    public int factorial(int i);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
public class PersonTest {
    public static void main(String[] args){

        Person p = i -> {
            //返回i的阶乘
            int sum=1;
            while (i>0){
                sum*=i;
                i--;
            }
            return sum;
        };
        //调用默认方法
        p.test("哈哈哈");
        //调用抽象方法
        int sum = p.factorial(5);
        System.out.println("5的阶乘为"+sum);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

运行结果
在这里插入图片描述

lambda表达式的用途及实例

使用lambda表示式的特点是延迟执行,毕竟如果是想立即执行代码的话,完全可以直接执行,不用把它放到lambda表达式里。(所以我上面写的例子可能体现不出lambda表达式的特点,只是为了让读者了解lambda表达式的编写及调用)
那哪些情况需要代码延迟执行呢 ? ,比如下列情况

  1. 在一个单独的线程中运行代码;
  2. 多次运行代码;
  3. 在算法的适当位置运行代码(例如, 排序中的比较操作);
  4. 发生某种情况时执行代码(如, 点击了一个按钮, 数据到达, 等等)
  5. 只在必要时才运行代码。

示例一:构造线程

  //使用匿名类方式构建线程
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hahahaha");
            }
        });
        thread.start();
        //使用lambda表达式
        Thread thread = new Thread(()-> System.out.println("hahahaha"));
        thread.start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

示例二:列表迭代

     List<String> languages = Arrays.asList("Java","C++","Python","JavaScript","C#");
        //一般的迭代遍历方式
        for (String language:languages){
            System.out.println(language);
        }
        //使用lambda表达式
        languages.forEach(n-> System.out.println(n));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

示例三:数组排序

 String[] languages = new String[]{"Java","C++","Python","JavaScript","C#"};
        //使用匿名类方式
        Arrays.sort(languages, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                //根据长度排序
                return o1.length()-o1.length();
            }
        });
        //使用lambda形式
        Arrays.sort(languages,(first,second)->first.length()-second.length());
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值