Java8 Lambda表达式

作者: mixiu | 来源:发表于2016-09-15 21:32 被阅读477次

第一个Lambda表达式

在Lambda出现之前,如果我们需要写一个多线程可能需要下面这种方式:

 Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello runnable");
            }
        };
        ...
 thread.start();

上面的例子如果改成使用Lambda就会简单许多:

 Runnable noArgs = ()->System.out.println("Hello Lambda!~");
...
 thread.start();

Lambda表达式是一个匿名函数,将行为像数据一样传递,表达式使用->将参数和主体分开,->前面是参数部分,后面这是主体部分。

Lambda的其它形式

 BinaryOperator<Long> add = (x,y)->x+y;
 //OR
 BinaryOperator<Long> add = (Long x,Long y)->x+y;
 //OR
 BinaryOperator<Long> add = (Long x,Long y)->{
    x+y;
 };
  • Lambda表达式使用()表示没有参数。
  • 如果Lambda表达式中只包含一个参数,可省略掉()
  • 如果Lambda表达式的主题是一段代码块,需要使用{},该代码块与普通的Java代码块并无区别,也可以返回或抛出异常。
  • 如果参数的类型可以由编译器推断得出可以省略参数类型,当然你也可以加上。

以上就是Lambda表达式的所有形式了。
那么问题来了:
BinaryOperator<Long> add = (Long x,Long y)->x+y;是个什么意思?

这行代码并不是讲个数字相加,而是创建了一个函数,用来计算两个数字相加的结果。而add的类型是BinaryOperator<Long>,它也不是两个数字的和,而是将两个数字相加的那段代码。下面的例子展示如何使用这个变量:

  BinaryOperator<Long> add = (Long x,Long y)->x+y;
  Long res = add.apply(3L, 4L);
  System.out.println("res="+res);//输出:res=7

函数接口

函数接口是只有一个抽象方法的接口,用作Lambda表达式的类型。
Runnable就是一个函数接口。
新建一个我们自己的函数接口:

public interface AddOperator<T,D> {
    long add(T one,D two);
}

使用:

 AddOperator<Long,Long> addOperator = ( x, y)->x +y;
 System.err.println("Custom function listener res= "+addOperator.add(34L, 65L));

目标类型

目标类型是指Lambda表达式所在上下文环境的类型。比如,将Lambda表达式赋值给一个局部变量,或传递给一个方法作为参数,局部变量或方法参数的类型就是Lambda表达式的目标类型。

final

如果我们在匿名内部类中引用了所在方法中的局部变量,这是需要局部变量是final的。
在Lambda中我们不需要将引用的外部局部变量声明为final的,但是该变量只能被赋值一次。
下面的例子中如果我们去掉注释,对name再次赋值,则无法通过编译,并显示出错信息:local variables referenced from a Lambda expression must be final or effectively final.
Lambda表达式引用的局部变量必须是final或即成事实的final。

String name = getUserName();
//name="hi";
button.addActionListener(event->System.out.println("name="+name));

类型推断

Lambda表达式的类型推断是Java7中就引入的目标类型推断的扩展。
java7中的类型推断:

List<String> list= new ArrayList<>();

上例中我们并没有指定ArrayList的范型类型,而是根据list的类型,推断出了ArrayList的范性类型。

如:AddOperator<Long,Long> addOperator = ( x, y)->x +y;

相关文章

网友评论

  • 42e9db8668ce:仁者见仁 智者见智
  • 36b1d63b7d75:lambda 表达式是个大坑,用起来很爽,如果不是常用的话,过半个月看就是一脸的懵逼,几年前C++11刚刚出来的时候用过一阵,后来被经理骂,被同事骂。。过一阵自己也懵逼了,就放弃了。。
  • 皮特天:我看过很多Lambda文章,你这篇很好,但我每次都有疑问:Lambda写起来是很方便,很帅,但是!很多情况下,我们对内部类的方法参数很熟悉很熟悉,才可以用的爽,你要是不知道方法参数什么意思?你怎么写?举个例子,rxandriod操作符基本都是接口一个方法参数,你达不到熟悉方法参数?怎么用?
    Kulbear:@TestSuper 函数式编程本身就不是很初级的东西 正常
    皮特天: @mixiu 对啊,所以我觉得矛盾,说明只适合熟手,新手完全不合适
    mixiu:@TestSuper 我觉得只有知道自己想要的参数类型时才能写出Lambda表达式,对于不知道类型的情况只能先用IDE看一下源码了。

本文标题:Java8 Lambda表达式

本文链接:https://www.haomeiwen.com/subject/jfivettx.html