为什么? 
   我们为什么需要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

转自:http://www.cnblogs.com/feichexia/archive/2012/11/15/Java8_LambdaExpression.html

Java 8 Lambda表达式探险的更多相关文章

  1. Java 8 Lambda表达式

    Java 8 Lambda表达式探险 http://www.cnblogs.com/feichexia/archive/2012/11/15/Java8_LambdaExpression.html 为 ...

  2. 深入浅出 Java 8 Lambda 表达式

    摘要:此篇文章主要介绍 Java8 Lambda 表达式产生的背景和用法,以及 Lambda 表达式与匿名类的不同等.本文系 OneAPM 工程师编译整理. Java 是一流的面向对象语言,除了部分简 ...

  3. Java 8 Lambda表达式10个示例【存】

    PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是 ...

  4. Java 8 Lambda 表达式

    Lambda 是啥玩意 简单来说,Lambda 就是一个匿名的方法,就这样,没啥特别的.它采用一种非常简洁的方式来定义方法.当你想传递可复用的方法片段时,匿名方法非常有用.例如,将一个方法传递给另外一 ...

  5. Java 8 lambda表达式示例

    例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现Runnable接口是匿名类的最好示例.看一下Java 8之前的runna ...

  6. Java 8 Lambda 表达式详解

    一.Java 8 Lambda 表达式了解 参考:Java 8 Lambda 表达式 | 菜鸟教程 1.1 介绍: Lambda 表达式,也可称为闭包,是推动 Java 8 发布的最重要新特性. La ...

  7. 用Java 8 Lambda表达式实现设计模式:命令模式

    在这篇博客里,我将说明如何在使用 Java 8 Lambda表达式 的函数式编程方式 时实现 命令 设计模式 .命令模式的目标是将请求封装成一个对象,从对客户端的不同类型请求,例如队列或日志请求参数化 ...

  8. Java基础学习总结(44)——10个Java 8 Lambda表达式经典示例

    Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Ja ...

  9. 02、Java的lambda表达式和JavaScript的箭头函数

    前言 在JDK8和ES6的语言发展中,在Java的lambda表达式和JavaScript的箭头函数这两者有着千丝万缕的联系:本次试图通过这篇文章弄懂上面的两个"语法糖". 简介 ...

随机推荐

  1. iOS之 opencv3.0.framework

    本文章的目的是从源代码包中编译出opencv2.framework供IOS开发使用. 基本上是按照http://docs.opencv.org/3.0-beta/doc/tutorials/intro ...

  2. 用最简单话概括SSH三框架

    Hibernate用来做持久层,因为它将JDBC做了一个良好的封装,程序员在与数据库进行交互时可以不用书写大量的SQL语句. Struts是用来做应用层的,他它负责调用业务逻辑serivce层,所以S ...

  3. Listener监听器与Filter过滤器

    1.Listener     [1]监听器简介         > Listener是JavaWeb的三大组件之一,Servlet.Filter.Listener         > Li ...

  4. 基于微软平台IIS/ASP.NET开发的大型网站有哪些?

    首先说明一下,本文绝不是要说Microsoft平台多么好,多么牛.只是要提醒一些LAMP/Java平台下的同志们,微软平台不至于像你们说的,和想象的那么不堪!只是你们自己不知道而已.同时,也希望广大M ...

  5. 使用CSS3滤镜让图片反转颜色

    CSS提供的滤镜也是一大亮点,我一直痴迷其中,有些滤镜的效果很有用,可是有些的滤镜效果可能只是为了玩玩儿,CSS常见的滤镜有这些:grayscale, blur, sepia,所有常见的过滤器.但是如 ...

  6. 创建android Notification

    说明:根据项目选择的基础sdk,选择不同的创建Notification的方法1 在android sdk 3.0 之前直接通过 new Notification的方法直接创建通知对象 2 在andro ...

  7. Python将MySQL表数据写入excel

    背景:将mysql表查询结果写入excel. 1.使用sqlyog工具将查询结果导出到Excel.xml中,用excel打开发现:因为text字段中有回车换行操作,显示结果行是乱的. 2.用mysql ...

  8. 烂泥:学习ssh之ssh密钥随身携带

    本文由秀依林枫提供友情赞助,首发于烂泥行天下 在上一篇文章<烂泥:学习ssh之ssh无密码登陆>中,我们讲解了如何使用ssh密钥,免密码登陆服务器. 这篇文章我们再来讲解,如何把已经生成的 ...

  9. Linux命令中使用正则表达式

    在使用grep.awk和sed命令时,需要使用正则表达式.比如我通过grep找代码编译结果中是否有错误.或者是否有我代码的错误.这里说下正则表达式基本的应用: • 匹配行首与行尾.• 匹配数据集.• ...

  10. 关于 RTL8723BS 同时开启 STA/AP 模式

    最近接到一个调试 wifi 驱动的任务,使用的是 rtl8723bs 芯片组.要求是让无线设备工作在 station 模式的时候同时开启一个 ap 热点.简单来讲就是连接其他 wifi 的同时发出一个 ...