java8之lambda表达式(变量作用域)

通常,我们希望能够在lambda表达式的闭合方法或类中访问其他的变量,例如:

package java8test;

public class T1 {
    public static void main(String[] args) {
        repeatMessage("Hello", 20);
    }
    public static void repeatMessage(String text,int count){
        Runnable r = () -> {
            for(int i = 0; i < count; i++){
                System.out.println(text);
                Thread.yield();
            }
        };
        new Thread(r).start();
    }
}

注意看lambda表达式中的变量count和text,它们并没有在lambda表达式中被定义,而是方法repeatMessage的参数变量。如果你思考一下,就会发现这里有一些隐含的东西。lambda表达式可能会在repeatMessage返回之后才运行,此时参数变量已经消失了。如果保留text和count变量会怎样呢?

为了理解这一点,我们需要对lambda表达式有更深入的理解。一个lambda表达式包括三个部分:

  • 一段代码
  • 参数
  • 自由变量的值,这里的“自由”指的是那些不是参数并且没有在代码中定义的变量。

在我们的示例中,lambda表达式有两个自由变量,text和count。数据结构表示lambda表达式必须存储这两个变量的值,即“Hello”和20。我们可以说,这些值已经被lambda表达式捕获了(这是一个技术实现的细节。例如,你可以将一个lambda表达式转换为一个只含一个方法的对象,这样自由变量的值就会被复制到该对象的实例变量中)。

注意:含有自由变量的代码块才被称之为“闭包(closure)”。在Java中,lambda表达式就是闭包。事实上,内部类一直都是闭包。Java8中为闭包赋予了更吸引人的语法。

如你所见,lambda表达式可以捕获闭合作用域中的变量值。在java中,为了确保被捕获的值是被良好定义的,需要遵守一个重要的约束。在lambda表达式中,被引用的变量的值不可以被更改。例如,下面这个表达式是不合法的:

public static void repeatMessage(String text,int count){
    Runnable r = () -> {
        while(count > 0){
            count--;        //错误,不能更改已捕获变量的值
            System.out.println(text);
            Thread.yield();
         }
     };
     new Thread(r).start();
}
时间: 2024-10-13 23:25:12

java8之lambda表达式(变量作用域)的相关文章

Android Stutio中使用java8的Lambda表达式

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51532028 本文出自:[openXu的博客] 目录: 为什么要使用Lambda表达式 让Android Stutio支持Lambda 函数式接口Functional interfaces Lambda表达式的目标类型以及匹配 Lambda表达式语法 1 基础语法和语法简化 2 Lambda表达式的词法作用域 3 变量捕获 ??Java 8的一个大亮点是引入Lambda表达式,使用它设计的

JAVA8之lambda表达式详解,及stream中的lambda使用

原文:http://blog.csdn.net/jinzhencs/article/details/50748202 lambda表达式详解 一.问题 1.什么是lambda表达式? 2.lambda表达式用来干什么的? 3.lambda表达式的优缺点? 4.lambda表达式的使用场景? 5.lambda只是一个语法糖吗? 二.概念 lambda表达式是JAVA8中提供的一种新的特性,它支持Java也能进行简单的"函数式编程". 它是一个匿名函数,Lambda表达式基于数学中的λ演算

java8之lambda表达式入门

1.基本介绍 lambda表达式,即带有参数的表达式,为了更清晰地理解lambda表达式,先上代码: 1.1 两种方式的对比 1.1.1 方式1-匿名内部类 class Student{ private String name; private Double score; public Student(String name, Double score) { this.name = name; this.score = score; } public String getName() { ret

java8之lambda表达式(函数式接口)

在Java中有许多已有的接口都需要封装代码块,例如:Runnable或者Comparator.lambda表达式与这些接口是向后兼容的.对于只包含一个抽象方法的接口,你可以通过lambda表达式来创建该接口的对象,这种接口被称为函数式接口.注意:Java8中接口可以声明非抽象的方法. 为了演示函数式接口转换,我们以Arrays.sort方法为例.该方法的第二个参数需要一个Comparator接口(该接口只含有一个方法)的实例.接下来我们编写一个简单的lambda表达式: Arrays.sort(

Java8中Lambda表达式详解

对于任何场景而言,代码量永远都是越少越好,而Java8中提供的Lambda表达式正式简化代码的利器. 参考博客:Java 8 Lambda 表达式详解 参考博客:完美的lambda表达式只有一行 在 Java 8 以前,若我们想要把某些功能传递给某些方法,总要去写匿名类. manager.addScheduleListener(new ScheduleListener() { @Override public void onSchedule(ScheduleEvent e) { // Event

Java8特性Lambda表达式

Lambda 表达式 简介: Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性. Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中). (parameters) -> expression 或 (parameters) ->{ statements; } 使用 Lambda 表达式需要注意以下两点: Lambda 表达式主要用来定义行内执行的方法类型接口,例如,一个简单方法接口.在上面例子中,我们使用各种类型的Lambda表达式来定义MathO

java8之lambda表达式(方法引用)

有些时候,你想要传递给其他代码的操作已经有实现的方法了.示例: button.setOnAction(event -> System.out.println(event); 如果你能够只将println方法传递给setOnAction方法,就更好了!下面是改后的代码: button.setOnAction(System.out::println); 表达式System.out::println是一个方法引用,等同于lambda表达式: x -> System.out.println(x) 正如

java8之lambda表达式(1)-基本语法

参考:http://www.cnblogs.com/andywithu/p/7344507.html lambda表达式,即带有参数的表达式,为更清晰地理解lambda表达式,先看如下例子: (1) class Student{ private String name; private Double score; public Student(String name, Double score) { this.name = name; this.score = score; } public S

Java8之Lambda表达式基础

Java 8中,将会提供对lambda的支持,函数式编程FP(Functional Programming)将会得到很好地支持,而函数式编程的一个重要特点就是适合并行运算. λ:希腊字母表中排序第十一位的字母,英语名称为Lambda,读音:兰亩达. 语法如下: (parameters) -> expression (parameters) -> statement (parameters) -> {statements;} 例子如下: () -> Math.PI * 2.0 (in