`

Lambda初探

 
阅读更多

为什么? 
   我们为什么需要Lambda表达式 
   主要有三个原因: 
   > 更加紧凑的代码 
     比如Java中现有的匿名内部类以及监听器(listeners)和事件处理器(handlers)都显得很冗长 
   > 修改方法的能力(我个人理解为代码注入,或者有点类似JavaScript中传一个回调函数给另外一个函数) 
     比如Collection接口的contains方法,当且仅当传入的元素真正包含在集合中,才返回true。而假如我们想对一个字符串集合,传入一个字符串,只要这个字符串出现在集合中(忽略大小写)就返回true。 
     简单地说,我们想要的是传入“一些我们自己的代码”到已有的方法中,已有的方法将会执行我们传入的代码。Lambda表达式能很好地支持这点 
   > 更好地支持多核处理 
     例如,通过Java 8新增的Lambda表达式,我们可以很方便地并行操作大集合,充分发挥多核CPU的潜能。 
     并行处理函数如filter、map和reduce。

 

怎么做? 
   实例1 FileFilter 

File dir = new File("/an/dir/");
   FileFilter directoryFilter = new FileFilter() {
      public boolean accept(File file) {
         return file.isDirectory();
      }
};

   通过Lambda表达式这段代码可以简化为如下:

File dir = new File("/an/dir/");
FileFilter directoryFilter = (File f) -> f.isDirectory();
File[] dirs = dir.listFiles(directoryFilter);

   进一步简化:

File dir = new File("/an/dir/");
File[] dirs = dir.listFiles((File f) -> f.isDirectory());


   Lambda表达式使得代码可读性增强了。我承认我开始学习Java的时候对那个匿名内部类感到很困扰,而现在Lambda表达式让这一切看起来都很自然(尤其是有.NET背景的童鞋会发现这个跟.NET中的Lambda表达式好像) 
   Lambda表达式利用了类型推断(type inference)技术:

编译器知道FileFilter只有一个方法accept(),所以accept()方法肯定对应(File f) -> f.isDirectory()
而且accept()方法只有一个File类型的参数,所以(File f) -> f.isDirectory()中的File f就是这个参数了,
.NET把类型推断做得更绝,如果上面用.NET Lambda表达式写法的话是这样的:
   File[] dirs = dir.ListFiles(f => f.isDirectory());
即压根就不需要出现File类型指示。

   实例2 Event Handler

Button bt = new Button();
   bt.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
         ui.showSomething();
      }
});


   使用Lambda表达式后:

Button bt = new Button();
ActionListener listener = event -> { ui.showSomething(); };
bt.addActionListener(listener);

   进一步简化: 

Button bt = new Button();
bt.addActionListener(event -> { ui.showSomething(); });

 

外循环、内循环和Map、Reduce、Filter 
   一直到现在,处理Java集合的标准做法是采用外循环。比如:

List<String> list = new ArrayList<String>();
list.add("hello");
list.add("world");
for(int item: list) {
   // 处理item
}

   还有迭代器循环,它们都是外循环,并且都是顺序处理(sequential handling)。顺序特性也常常引发ConcurrentModificationException,只要我们尝试着并发修改集合。 
   Lambda表达式提供了内循环机制。 
   我们工作中可能经常面临下面的需求:

> 过滤掉一个集合中不符合条件的元素得到一个新集合
> 对集合中的每个元素进行某种转换,并且对转换后的集合进行处理
> 统计整个集合的某个属性,比如统计集合元素值的总和或平均值

   这些任务即filter、map和reduce,他们的共同特点是: 
   需要对集合中的每个元素运行一小段相同的代码。 
   传统的实现这些任务的代码让人感到很乏味,幸运的是Java 8提供了完成这些任务的更简洁的方案,当然还是利用Lambda表达式,但也引入了一个新的类库java.util.functions,包含Predicate、Mapper和Block。 
   Java 8中,一个Predicate(谓词)是这样一个方法:它根据变量的值进行评估(evaluate),返回true或false。 
   比如下面:

List<String> list = getMyStrings();
for(String myString: list) {
   if(myString.contains(possible)) {
       System.out.println(myString + " contains " + possible);
   }
}

   使用Predicate和Filter后得到下面代码:

List<String> list = getMyStrings();
Predicate<String> matched = s -> s.equalsIgnoreCase(possible);
list.filter(matched);

   进一步简化:

List<String> list = getMyStrings();
list.filter(s -> s.equalsIgnoreCase(possible));

 

Lambda表达式语法规则 
   到目前为止Java 8中的Lambda表达式语法规则还没有完全确定。 
   但这里简单介绍下: 
   对于前面的:

File dir = new File("/an/dir/");
File[] dirs = dir.listFiles((File f) -> f.isDirectory());

   accept()方法返回布尔值,这种情况f.isDirectory()显然也得是布尔值。这很简单。 
   而对于:

Button bt = new Button();
bt.addActionListener(event -> { ui.showSomething(); });

   actionPerformed()方法的返回类型是void,所以需要特殊处理,即在ui.showSomething();左右加上花括号。(想象下不加会怎么样?如果不加的话,若showSomething()方法返回值是整数类型,那么就意味着actionPerformed()返回整数类型,显然不是,所以必须加花括号用来标记)。 
   如果Lambda表达式主体部分包含多条语句,也必须用花括号,并且return语句不能省。 
   比如下面这个:

File dir = new File("/an/dir/");
File[] dirs = dir.listFiles((File f) ->  { 
                                            System.out.println("Log:...");
                                            return f.isDirectory(); 
                                         }
);

 

参考自:http://www.oraclejavamagazine-digital.com/javamagazine/20121112?sub_id=hlBuL1SAFxXX#pg35

 
 
分享到:
评论

相关推荐

    Java Lambda表达式初探

    Java 8一个重要的变更是引入Lambda表达式(lambda expression),这听起来似乎很牛,有种我虽然不知道Lambda表达式是什么,但我仍然觉得很厉害的感觉。不要怕,具体到语言层面上Lambda表达式不过是一种新的语法而已,...

    Kotlin初探与集成Android项目

    ### Kotlin初探与集成Android项目 #### 一、了解Kotlin **Kotlin的背景:** Kotlin 是一种由 JetBrains 开发的静态类型编程语言,它最初发布于 2011 年,并且在 2017 年被 Google 宣布成为 Android 的官方开发...

    DDD领域驱动设计初探(7):Web层的搭建 - 文章 - 伯乐在线1

    《DDD领域驱动设计初探(7):Web层的搭建》 在软件开发中,领域驱动设计(Domain-Driven Design,简称DDD)是一种强调以业务领域为中心的开发方法论。在DDD实践中,系统通常被划分为多个层次,包括领域层、应用层...

    Matlab在概率统计教学中的应用初探.pdf

    - poissrnd(lambda,m,n):生成一个m行n列的泊松分布随机数矩阵,其中lambda为单位时间(或单位面积)内的平均发生次数。 - randn(m,n):生成一个m行n列的正态分布随机矩阵,数学期望为0,方差为1。 - normrnd(mu,...

    Serverless架构理论与实践初探

    BaaS提供后台服务,如数据库、身份验证等,而FaaS则专注于运行开发者定义的函数,这些函数在无状态的计算环境中按需触发,如AWS Lambda。 Serverless架构的特点之一是免维护,开发者无需担心服务器的状态,因为云...

    C#委托与事件初探

    从C# 3.0开始,匿名方法和Lambda表达式使得不需显式定义方法即可创建委托实例。例如: ```csharp CheckDelegate anon = (int num) =&gt; Console.WriteLine("匿名方法: " + num * num); ``` ### 五、事件的最佳实践 ...

    python详细学习教程.rar

    第二章:Python初探 第三章:变量类型和运算符 第四章:列表,元组,字典和集合 第五章:Python字符串常用方法 第六章:Python流程控制 第七章:函数和lambda表达式 第八章:Python类和对象 第九章:Python异常处理...

    Python学习教程(超级详细)中文PDF完整版最新版本

    目录第1章Python编程基础第2章Python初探第3章变量类型和运第4章列表、元组、字典和集合第5章Python字符串常用方法第6章Python 流程控制第7章函数和 lambda表达式第8章Python 类和对象第9章Python异常处理机制第10章...

    C++11 并发指南之多线程初探

    除了上述多线程特性,C++11还有其他重要的新特性,如右值引用(move semantics)、完美转发(perfect forwarding)、类型推断(auto)、lambda表达式等,它们极大地增强了C++的灵活性和效率。 了解和掌握C++11的多...

    初探TensorFLow从文件读取图片的四种方式

    dataset = dataset.map(lambda x: tf.io.read_file(x)) dataset = dataset.map(tf.io.decode_jpeg) iterator = dataset.make_one_shot_iterator() next_element = iterator.get_next() with tf.Session() as ...

    线性代数初探(行列式,矩阵初等变换,矩阵的秩)

    引言:边听网课边看线性代数,爽! 线代太好玩了,鉴于博主的老年记忆,赶紧记录下来 本文主要介绍行列式的一些性质与应用,还有矩阵的一些运算 大概是《线性代数》的精简版外加一些自己的理解 ...

    flink1.12入门到精通视频课程

    11-[掌握]-Flink入门案例-代码实现-2-DataStream流批一体-Lambda版 12-[掌握]-Flink入门案例-代码实现-2-DataStream流批一体-On-Yarn 13-[掌握]-Flink原理初探-角色分工-执行流程-DataFlow 14-[掌握]-Flink原理初探-...

    CPP.rar_visual c

    《C++编程初探——以Visual C++为实践平台》 C++,作为一门强大的面向对象编程语言,深受程序员喜爱,尤其在系统级编程、游戏开发、高性能计算等领域有着广泛的应用。Visual C++是Microsoft公司推出的集成开发环境...

    Java-program-design-.rar_Java 8

    2. **第二章 - Java初探** 这一章将引导读者了解Java的历史、特点和应用领域。会讲解Java的“一次编写,到处运行”的跨平台特性,以及其面向对象编程的基础。可能会包含如何安装Java开发环境(JDK)和编写第一个...

    library.zip

    《Java Web图书馆课程设计——基于Eclipse、MySQL与Tomcat的初探》 在IT行业中,Java Web技术作为企业级应用的重要开发平台,一直是程序员学习的热点。本课程设计项目"library.zip"就是一个很好的入门实践,它利用...

    readMe.pdf

    技术基础章节介绍了使用Java 8作为开发语言的多项特性,例如Lambda表达式、Stream API、Optional类以及函数式接口等,这些是现代Java开发中不可或缺的技术点。同时,还包括了Lombok的使用,它可以简化Java代码的编写...

    MForMethods:第一回购

    《C#编程基础与MForMethods初探》 在编程世界中,C#是一门强大且广泛应用的语言,尤其在微软的.NET平台上,它的地位尤为重要。本文将围绕"MForMethods"这一主题,结合C#的基础知识,深入探讨在C#中如何理解和使用...

    聖殿祭司的ASP.NET 3.5專家技術手冊II新功能篇--使用C# 试读目录

    - **Lambda Expressions**:通过Lambda表达式简化了委托的创建过程,提高了代码的可读性和可维护性。 - **扩展方法**:允许向现有类型添加新的实例方法,无需修改该类型本身的代码。 - **自动属性实作**:简化了属性...

    cheapbot:廉价机器人

    《廉价机器人——Kotlin语言构建智能应用初探》 在当今科技日新月异的时代,机器人技术不再遥不可及,而是逐渐渗透到我们日常生活的各个角落。"cheapbot"项目正是这样一个实例,它以低廉的成本,展示了机器人技术的...

Global site tag (gtag.js) - Google Analytics