当前位置: 代码迷 >> .NET新技术 >> 什么是 Lambdas 表达式 ?解决方案
  详细解决方案

什么是 Lambdas 表达式 ?解决方案

热度:400   发布时间:2016-04-25 01:25:37.0
什么是 Lambdas 表达式 ?
本帖最后由 Jelly1989 于 2014-03-14 09:55:42 编辑
博客园上看到说,Java 8 中将加入Lambdas 表达式,这是个什么东西?

C#中有类似的功能吗?
------解决方案--------------------
Lambda 表达式
http://msdn.microsoft.com/zh-cn/library/bb397687.aspx
  
*****************************************************************************
签名档: http://feiyun0112.cnblogs.com/
------解决方案--------------------
引用:
Quote: 引用:

Lambda 表达式
http://msdn.microsoft.com/zh-cn/library/bb397687.aspx
  
*****************************************************************************
签名档: http://feiyun0112.cnblogs.com/


它不是有个s吗,是lambda的复数版?

怎么看怎么像是笔误啊
------解决方案--------------------
java和c#的语法本来就很类似
------解决方案--------------------
C#、Java都有,百度一下,资料很多
------解决方案--------------------
总归要改点东西吧~~

就像那个啥cos之类的~~

名字什么的都一样就不好了~~
------解决方案--------------------
Lambda工程是即将到来的Java8的一大主题,可能也是程序员们最期待已久的东西。随着Java lambdas的到来,还有一个有趣的东西被附带的加进了Java语言——defender(守卫者)方法。在这篇文章里,我的目的是要看看面纱后的东西 ——看看在运行时环境里lambdas是表现的,在方法的调度过程中涉及到哪些字节码指令。
尽管Java 8还没有正式发布,我们仍然可以下载各种平台上的早期预览版,在其上做简单的尝试。
你也想试试lambdas,是吗?
如果你熟悉其它的还有lambda表达式的编程语言,比如Groovy 或 Ruby,当第一眼看到Java里的lambda时,你也许会吃惊于它的不简单。在Java里,lambda表达式是“SAM”(Single Abstract Method)——一个含有一个抽象方法的接口(是的,现在接口里可以含有一个非抽象的方法,defender守卫方法)。
举个例子,大家熟知的Runnable接口就可以完美的被当作一个SAM类型:
Runnable r = () -> System.out.println("hello lambda!"); 
,这同样也适用于Comparable接口:
Comparator<Integer> cmp = (x, y) -> (x < y) ? -1 : ((x > y) ? 1 : 0); 
写成下面的样子也是一样的:
Comparator<Integer> cmp = (x, y) -> {  
  return (x < y) ? -1 : ((x > y) ? 1 : 0);  
}; 
从中可以看出,单行的lambda表达式似乎是隐含了一个return语句。
那么,如何写一个能接受lambda表达式作为参数的方法呢?这样,你需要先把这个参数声明成函数式的接口,然后把lambda传入:
interface Action {  
   void run(String param);  
}  
 
public void execute(Action action){  
   action.run("Hello!");  

一旦有了一个能将函数式接口作为参数的方法,我们就可以像下面这样调用它:
execute((String s) -> System.out.println(s)); 
还可以更简洁,这个表达式可以被替换成对一个方法的引用,因为它只是单个方法,而且它们的参数是相同的:
execute(System.out::println); 
然而,如果参数上有任何其它形式的变化,我们就不能直接引用方法,必须写全lambda表达式:
execute((String s) -> System.out.println("*" + s + "*")); 
我觉得这种语法还是相当漂亮的,现在,Java语言里有了一个非常优雅的lambdas解决方案,尽管Java里并不存在函数式类型。
JDK 8里的函数式接口
我们已经知道,lambda在运行时的表现形式是一个函数式的接口(或“SAM类型”)——只有一个抽象方法的接口。尽管JDK里已经有了不少这样的接口,例如Runnable 和 Comparable ,它们符合这种标准,但很显然,对于一个新API的进化来说,这是不够的。我们不可能所有地方都用Runnables接口。
在JDK 8 里有个新包,java.util.function,里面包含了很多函数式接口,都是提供在新API里使用的。我不想把它们全列出来——你们自己可以去看一下,学习一下这个新包
但看起来这个新包在不断的变化,经常性的一些新接口会出现而另一些会消失。例如,以前曾有过 java.util.function.Block 这个类,最新的版本中却没有它,我写这篇博客时使用的版本是:
anton$ java -version  
openjdk version "1.8.0-ea" 
OpenJDK Runtime Environment (build 1.8.0-ea-b75)  
OpenJDK 64-Bit Server VM (build 25.0-b15, mixed mode) 
我研究发现,它现在被 Consumer 接口替代,collection包里的所有新方法都将使用它。例如,Collection接口里定义了forEach方法,如下:
public default void forEach(Consumer<? super T> consumer) {  
  for (T t : this) {  
    consumer.accept(t);  
  }  

Consumer接口里一个有趣地方是,它实际上定义了一个抽象方法——accept(T t)和一个defender方法——Consumer<T> chain(Consumer<? extend T> consumer)。这就是说你可以链式调用这个接口。我不确定如何使用,因为我在JDK包里没有找到chain(..)的使用方法说明。
我还发现所有的接口都使用了@FunctionalInterface运行时注注解注释。这个注释不仅仅是个说明,它还被javac使用来验证这个接口是否真是一个函数式接口,是否至少有一个抽象方法在里面。
所以,如果我们来编译下面的这段代码
@FunctionalInterface 
interface Action {  
  void run(String param);  
  void stop(String param);  

编译器会告诉我们:
java: Unexpected @FunctionalInterface annotation  
  Action is not a functional interface 
    multiple non-overriding abstract methods found in interface Action 
而下面的就能编译通过:
@FunctionalInterface 
interface Action {  
  void run(String param);  
  default void stop(String param){}  

反编译lambdas
我对语法语言特征其实并不是很好奇,我更好奇的是这些特征在运行时的表现形式,这就是为什么我像往常一样,拿起我喜爱的javap工具,开始查看lambdas里的这些类的字节码。
目前(在Java 7之前),如果你想在Java里模拟lambdas,你需要定义一个匿名的内部类。它在编译后会产生一个具体的class。如果你在一段代码里定义了多个这样的类,你会发现这些类后面会跟着一些数字。那lambdas也会这样吗?
看看下面的这段代码:
public class Main {  
 
  @FunctionalInterface 
  interface Action {  
    Object run(String s);  
  }  
 
  public void action(Action action){  
  相关解决方案