求花样排球花样排球12百度云资源源

.NET 3.x新特性之Lambda表达式
.NET 3.x新特性之Lambda表达式
lambda 表达式格式为:
(参数列表) =& 表达式或者语句块
分为三个步骤
1、(参数列表):
2、=&符号可以理解为从
3、表达式或者语句块
可以有多个参数,一个参数,或者无参数。参数类型可以隐失或者显示。例如:
(x,y) =& x * y&&& //多参数,隐式类型=&表达式
x =& x * 10&&& //单参数,隐式类型=&表达式
x =& {return x * 10;}&& //单参数,隐失类型=&语句块
(int x) =& x * 10&& //单参数,显示类型=&表达式
(int x) =& {return x * 10} //单参数,显示类型=&语句块
() =& Console.WriteLing() //无参数
Lambda表达式其实是一个委托类型实例,编译器会根据参数的类型建立一个同类型的同参数的委托:
x =& x * 10&
相当于是下面一个委托类型的实例
delegate int MyDeg(int i);//这个是由编译器根据推断出的类型而建立的
只不过这些工作由编译器帮我们做了
Lambda 表达式格式要点
- Lambda表达式的参数类型可以忽略,因为可以根据使用的上下文进行推断。
- Lambda表达式的主体(body)可以是表达式,也可以是语句块。
- Lambda表达式传入的实参将参与类型推断,以及方法重载辨析。
- Lambda表达式和表达式体可以被转换为表达式树。
Lambda 表达式与委托类型
Lambda 表达式L可以被转换为委托类型D,需要满足以下条件:
- L和D拥有相同的参数个数。
- L的参数类型要与D的的参数类型相同。注意隐式类型要参与类型辨析。
- D的返回类型与L相同,无论L是表达式,还是语句块。
下面我们来看一下编译器到底都做了些什么?
比如在程序中有下面Lambda表达式:
delegate bool Mydelegate(string s);
&&& public static Process(Mydelegate myd)
&&&&&&& {&
&&&&&&&&&&& myd(&wo shi jhxz&);
jh.Process(s =& s.Indexof(&jhxz&) & 0) //Process方法接受一个Mydelegate的委托
编译其实有Lambda表达式那条语句编译为以下这样的代码:
Mydelegate md=new Mydelegate(IsValidXXXX);//编译器生成
jh.Process(md1)
public static bool IsValidXXXX(string s)//编译器生成
  return s.Indexof(&jhxz&) & 0;
1.准备测试数据
static&int[] numbers&=&new&int[] {&5,&4,&1,&3,&9,&8,&6,&7,&2,&0&};
static&string[] strings&=&new&string[] {&&zero&,&&one&,&&two&,&&three&,&&four&,&&five&,&&six&,&&seven&,&&eight&,&&nine&};
class&Person {
public&string&N
public&int&L
static&Person[] persons&=&new&Person[] {
new&Person {Name=&Matt&, Level=3},
new&Person {Name=&Luca&, Level=3},
new&Person {Name=&Jomo&, Level=5},
new&Person {Name=&Dinesh&, Level=3},
new&Person {Name=&Charlie&, Level=3},
new&Person {Name=&Mads&, Level=3},
new&Person {Name=&Anders&, Level=9}
2.过滤数据
public&static&void&Sample1() {
//&use Where() to filter out elements matching a particular condition&&&&&&&
&&&&&&& IEnumerable&int&&fnums&=&numbers.Where(n&=&&n&&&5);
Console.WriteLine(&Numbers & 5&);
foreach(int&x&in&fnums) {
Console.WriteLine(x);
3.匹配首个字母
public&static&void&Sample2() {
//&use First() to find the one element matching a particular condition&
&&&&&&&&string&v&=&strings.First(s&=&&s[0]&==&'o');
Console.WriteLine(&string starting with 'o': {0}&, v);
4.根据numbers排序
public&static&void&Sample3() {
//&use Select() to convert each element into a new value
&&&&&&& IEnumerable&string&&snums&=&numbers.Select(n&=&&strings[n]);
Console.WriteLine(&Numbers&);
foreach(string&s&in&snums) {
Console.WriteLine(s);
5.匿名类型,注意var关键字
public&static&void&Sample4()
//&use Anonymous Type constructors to construct multi-valued results on the fly
&&&&&&& var q&=&strings.Select(s&=&&new&{Head&=&s.Substring(0,1), Tail&=&s.Substring(1)});
foreach(var p&in&q) {
Console.WriteLine(&Head = {0}, Tail = {1}&, p.Head, p.Tail);
6.联合查询(即使用两个以上的查询条件)
public&static&void&Sample5() {
//&Combine Select() and Where() to make a complete query
&&&&&&& var q&=&numbers.Where(n&=&&n&&&5).Select(n&=&&strings[n]);
Console.WriteLine(&Numbers & 5&);
foreach(var x&in&q) {
Console.WriteLine(x);
7.使用ToList方法
public&static&void&Sample6() {
//&Sequence operators form first-class queries are not executed until you enumerate them.
&&&&&&&&int&i&=&0;
var q&=&numbers.Select(n&=&&++i);
//&Note, the local variable 'i' is not incremented until each element is evaluated (as a side-effect).
&&&&&&&&foreach(var v&in&q) {
Console.WriteLine(&v = {0}, i = {1}&, v, i);
Console.WriteLine();
//&Methods like ToList() cause the query to be executed immediately, caching the results
&&&&&&&&int&i2&=&0;
var q2&=&numbers.Select(n&=&&++i2).ToList();
//&The local variable i2 has already been fully incremented before we iterate the results
&&&&&&&&foreach(var v&in&q2) {
Console.WriteLine(&v = {0}, i2 = {1}&, v, i2);
8.分组查询
public&static&void&Sample7() {
//&use GroupBy() to construct group partitions out of similar elements
&&&&&&& var q&=&strings.GroupBy(s&=&&s[0]);&//&&- group by first character of each string
foreach(var g&in&q) {
Console.WriteLine(&Group: {0}&, g.Key);
foreach(string&v&in&g) {
Console.WriteLine(&\tValue: {0}&, v);
9.统计聚合
public&static&void&Sample8() {
//&use GroupBy() and aggregates such as Count(), Min(), Max(), Sum(), Average() to compute values over a partition
&&&&&&& var q&=&strings.GroupBy(s&=&&s[0]).Select(g&=&&new&{FirstChar&=&g.Key, Count&=&g.Count()});
foreach(var v&in&q) {
Console.WriteLine(&There are {0} string(s) starting with the letter {1}&, v.Count, v.FirstChar);
//&use OrderBy()/OrderByDescending() to give order to your resulting sequence
&&&&&&& var q&=&strings.OrderBy(s&=&&s);&//&order the strings by their name
foreach(string&s&in&q) {
Console.WriteLine(s);
11.二次排序
public&static&void&Sample9a() {
//&use ThenBy()/ThenByDescending() to provide additional ordering detail
&&&&&&& var q&=&persons.OrderBy(p&=&&p.Level).ThenBy(p&=&&p.Name);
foreach(var p&in&q) {
Console.WriteLine(&{0} {1}&, p.Level, p.Name);
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
Lambda表达式供参习.doc 15页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
需要金币:289 &&
Lambda表达式供参习
你可能关注的文档:
··········
··········
在我们程序中,经常有这样一些需求: 1.??????需要一个临时方法,这个方法只会使用一次,或者使用的很少。 2.??????这个方法的方法体很短,以至于比方法声明都短,写起来实在没劲(我将其称之为“一句话方法”)。 没办法,这样的方法写起来真是吃力不讨好,比如一些按钮事件处理中,有些按钮点击就是弹出一个对话框,或者调用一下别的什么方法。比如下面的代码:this.btnRefresh.Click?+=?new?System.EventHandler(this.btnRefresh_Click); private?void?btnRefresh_Click(object?sender,?EventArgs?e) { ????BindData(); }这个”Refresh”按钮就是做一下调用一下BindData()数据绑定的方法,为此我们不得不写一个新方法。好了,C#2.0为我们提供了匿名方法:this.btnRefresh.Click?+=?delegate(object?sender,?EventArgs?e)?{?BindData();?};没劲的代码没了。想知道这种写法的幕后黑手么? 其实编译器还是在我们的后面干了一件龌龊的事情:它为我们产生了一个新的方法,它只是表面上为我们节省了代码。privatevoid&Test&b__0(object?sender,?EventArgs?e) { ????this.BindData(); }看看这个编译器产生的方法的名称: &Test&b_0,Test是这个匿名方法所放置的地方(因为这个按钮的时间我是放在一个Test方法里的) 还有一点需要注意的是,如果这个匿名方法是在实例方法里使用,那么编译器为我们生成的幕后方法也是实例方法,否则就是静态方法了. 是不是觉得匿名方法这东西很不错,减少了很多代码阿,但是匿名方法的使用还并不人性化,什么是人性化呢?比如你可以用自然的语言将程序代码读出来,这样才算人性化了.在.net2.0中System.Collections.Generic命名空间下List&T&里有一些新增的方法。比如Find,如果使用匿名方法我们如何调用呢:books.Find(delegate(Book?book){return?book.Price?&?50;});代码是很简单,但是却无法朗读出来,来看看Lambda表达式的写法: books.Find(book=&book.Price&50);这个Lambda表达式就可以这样阅读出来了:给你一本书,如果它的价格小于50则返回true。 好了,那我们就走进Lambda表达式吧: ?将使用了Lambda表达式的程序集反编译后,我们发现,它实际上和匿名方法没有什么不同。Lambda的输入参数就对应着delegate括号里面的参数,由于Lambda表达式可以推断参数的类型,所以这里的参数无需声明。Lambda操作符读作”Goesto”,它后面紧跟着表达式或者是语句块(这点和匿名方法也不同,匿名方法只能使用语句块而不能使用表达式),下面我就用实例来说明一下有那些类型的Lambda表达式: //x的类型省略了,编译器可以根据上下文推断出来,后面跟着的是表达式 x?=&x+1? deleage(intx){returnx+1;} //后面跟着的是语句块 x=&{returnx+1;} delegate(intx){returnx+1;} //输入参数也可以带类型,带类型后别忘记小括号哦 (intx)=&x+1 delegate(intx){returnx+1;} //也可以多个输入参数,逗号分隔,别忘记小括号 (x,y)=&x+y delegate(intx,inty){returnx+y;} //无参的也行()=&1delegate(){return1;}对于Lambda表达式来说她的用法就是如此,但是在Lambda背后却有很多的故事和玄机。用Lambda表达式可以构建表达式树,而表达式树对于Linq来说就像树根对于树一样重要。在这里就不讨论表达式树的问题了,这个东西也不是三言两语能够说清楚的,等待时机成熟的时候我们再来进一步讨论。Lambda表达式更多阅读Lambda实际上源远流长,我们现在使用的机器都是冯-诺依曼体系的,属于图灵机,在那之前还有一种称作λ演算的理论,但是图灵机由于先被实现出来,所以大行其道,λ演算后来成就了函数式编程语言特别是Lisp,在函数式编程语言里函数是第一等元素,函数的参数,函数的返回值都是函数,程序没有变量,函数嵌套函数。而且函数式编程语言一直存在于象牙塔中,所以在工业界并没有得到通用,不过近年来工业界比较喜欢“复古”风格
正在加载中,请稍后...Lambda表达式
一、Lambda表达式学习笔记
在C#2.0中引入了匿名方法允许在期望出现委托的时候以“内联”的代码替代之。尽管匿名方法提供了函数式编程语言中的很多表达能力,但匿名方法的语法实在是太“不近人情”了,并且很不自然,用多了会造成阅读上的困难。举例来说:
class&Test
&&&&&&&&public&static&void&Main()
&&&&&&&&&&&
&&&&&&&&&&&&List&int&&intList&=&new&List&int&();
&&&&&&&&&&&&var&numArr&=&new&int[]&{&<span STYLE="CoLor: #,&<span STYLE="CoLor: #,&<span STYLE="CoLor: #,&<span STYLE="CoLor: #,&<span STYLE="CoLor: #,&<span STYLE="CoLor: #,&<span STYLE="CoLor: #3,&<span STYLE="CoLor: #&};
&&&&&&&&&&&&intList.AddRange(numArr);
&&&&&&&&&&&&intList.Sort(delegate(int&a,&int&b)&//匿名方法
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&return&<pareTo(b);
&&&&&&&&&&&&});
&&&&&&&&&&&&foreach&(var&item&in&intList)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&Console.WriteLine(item);
&&&&&&&&&&&&}
&&&&&&&&&&&&Console.Read();
上面的匿名委托我们可以简化为Lambda表达式来表示。实际上Lambda表达式的本质是匿名方法,也即是当编译我们的程序代码时,编译器会自动帮我们将Lambda表达式转换为匿名方法。看下改进后的代码:
下面系统学习Lambda表达式的相关语法和应用:
Lambda表达式的书写方式是一个参数列表后跟“=&”记号,然后跟一个表达式或一个语句块,即Lambda表达式的语法格式为:参数列
=& 语句或语句块。
(param1,&param2,&…paramN)&=&
statement1;
statement2;
statementN;return(lambda_expression_return_type);
2、关于“参数列”
Lambda表达式的参数列可以具有显式的或隐式的类型。在一个具有显式类型的参数列表中,每个参数的类型都是显式声明的。在一个具有隐式类型的参数列表中,参数的类型是从Lambda表达式出现的上下文中推断出来的——具体来说,是当Lambda表达式被转换为一个兼容的委托类型时,该委托类型提供了参数的类型。
当Lambda表达式只有一个具有隐式类型的参数时,参数列表中的括号可以省略。即:(param)
=& expression可以简写为:param =&
expression。
注意,参数列中可包含任意个参数(与委托对应),如果参数列中有0个或1个以上参数,则必须使用括号括住参数列,举例如下:
() =& Console.Write("0个参数");
Console.Write("1个参数时参数列中可省略括号,值为:{0}", i);
Console.Write("包含2个参数,值为:{0}:{1}", x, y);
而“语句或语句块”中如果只有一条语句,则可以不用大括号括住,否则则必须使用大括号,如下所示:
&//只有一条语句,则可以不用大括号括住
&i =& Console.Write("只有一条语句");
=& { Console.Write("使用大括号的表达式"); };
&//两条语句时必须要大括号
&i =& { i++;
Console.Write("两条语句的情况"); };
如果“语句或语句块”有返回值时,如果只有一条语句则可以不写“return”语句,编译器会自动处理,否则必须加上,如下示例:
class&MyCsTest
&&&&&&&&delegate&int&AddOperation(int&x,&int&y);
&&&&&&&&static&void&Print(AddOperation&add)
&&&&&&&&&&&&Console.Write(add(<span STYLE="CoLor: #,&<span STYLE="CoLor: #));
&&&&&&&&static&void&Main()
&&&&&&&&&&&&Print((x,&y)&=&&x&+&y);&//可以不写return
&&&&&&&&&&&&Print((x,&y)&=&&{&int&i&=&x&*&<span STYLE="CoLor: #;&return&y&+&i;&});
&&&&&&&&&&&&Console.Read();
3、遵循规则
Lambda表达式是委托的实现方法,所以必须遵循以下规则:
(1)Lambda表达式的参数数量必须和委托的参数数量相同;
(2)如果委托的参数中包括有ref或out修饰符,则Lambda表达式的参数列中也必须包括有修饰符;
(3)如果委托有返回类型,则Lambda表达式的语句或语句块中也必须返回相同类型的数据;
(4)如果委托有几种数据类型格式而在Lambda表达式中编译器无法推断具体数据类型时,则必须手动明确数据类型。
示例如下:
class&MyCsTest
&&&&&&&&delegate&void&OutHandler(out&int&x);
&&&&&&&&static&void&Print(OutHandler&test)
&&&&&&&&&&&&int&i;
&&&&&&&&&&&&test(out&i);
&&&&&&&&&&&&Console.Write(i);
&&&&&&&&static&void&Main()
&&&&&&&&&&&&Print((out&int&x)&=&&x&=&<span STYLE="CoLor: #);&//out参数&
&&&&&&&&&&&&Console.Read();
2.0规范中提到的匿名方法规范同样适用于Lambda表达式。Lambda表达式是匿名方法在功能行上的超集,提供了下列附加的功能:
(1)Lambda表达式允许省略参数类型并对其进行推断,而匿名方法要求参数类型必须显式地声明。
(2)Lambda表达式体可以是表达式或语句块,而匿名方法体只能是语句块。
(3)在类型参数推导和方法重载抉择时,Lambda表达式可以被作为参数传递。
(4)以一个表达式作为表达式体的Lambda表达式可以被转换为表达式树。
4、Lambda表达式的转换
两个代表:下面行文中的D代表Delegate(委托类型),L代表Lambda表达式
和匿名方法表达式类似,Lambda表达式可以归类为一种拥有特定转换规则的值。这种值没有类型,但可以被隐式地转换为一个兼容的委托类型。
特别地,当满足下列条件时,委托类型兼容于Lambda表达式:
(1) D和L具有相同数量的参数;
(2) 如果L具有显式类型的参数列表,D中每个参数的类型和修饰符必须和L中相应的参数完全一致;
(3) 如果L具有隐式类型的参数列表,则D中不能有ref或out参数;
如果D具有void返回值类型,并且L的表达式体是一个表达式,若L的每个参数的类型与D的参数一致,则L的表达式体必须是一个可接受为statement-expression的有效表达式;
如果D具有void返回值类型,并且L的表达式体是一个语句块,若L的每个参数的类型与D的参数一致,则L的表达式体必须是一个有效语句块,并且该语句块中不能有带有表达式的return语句;
如果D的返回值类型不是void,并且L的表达式体是一个表达式,若L的每个参数的类型与D的参数一致,则L的表达式体必须是一个可以隐式转换为D的返回值类型的有效表达式;
如果D的返回值类型不是void,并且L的表达式体是一个语句块,若L的每个参数的类型与D的参数一致,则L的表达式体必须是一个有效的语句块,该语句块不能有可达的终点
(即必须有return语句),并且每个return语句中的表达式都必须能够隐式转换为D的返回值类型。
(ps:ms这里的约束也太多了吧^_^。哎,不管了,先抄下来,以后会熟练运用就行了)
二、一个需要注意的地方
看下面的代码:
using&Susing&System.Collections.G
using&System.L
namespace&MyCsStudy
&&&&class&Program
&&&&&&&&static&void&Main(string[]&args)
&&&&&&&&&&&&List&Func&int&&&list&=&new&List&Func&int&&();
&&&&&&&&&&&&for&(int&i&=&<span STYLE="CoLor: #;&i&&&<span STYLE="CoLor: #;&i++)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&list.Add(()&=&&i);&//list依次添加0,1,2??
&&&&&&&&&&&&}
&&&&&&&&&&&&foreach&(var&item&in&list)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&Console.WriteLine(item());&//输出的竟然是?
&&&&&&&&&&&&}
运行试一下看看结果,如果你以前碰到过js里的问题,相信你不会大惊小怪(而且可能已经知道了问题的原因),但是,如果你从来没有碰到过这种情况,是不是令你大吃一惊?!输出的竟然不是0,1,2,而是三个3,oh,my
god。紧接着,立刻,你会大胆想到这里的list在Add方法执行的地方Add进去的是一个引用类型(这里是lambda表达式()=&i),它们执行的结果共同指向值为3的同一个引用地址!
没错,我们详细分析一下:
1、我们首先定义一个list,其存储格式为func&int&,即返回int型的代理;然后,用for循环将i封装进lambda表达式,并加入到该list中,最后,用foreach循环输出结果。
2、因为lambda表达式实质就是个委托,也就指向一个匿名函数,所以,在foreach输出的时候,使用item()来调用它,让它所指向的函数执行。
至于第2步中item()执行的结果为什么都是3,原因是这样的:
(1)在for循环中,只能有一个 i 变量。即在第一次循环时,i
的地址就分配好了(注意了,这里i的地址第一次分配后是不变的),不会因为循环次数的多少而发生任何改变,其改变的只能是里面装载的值。
(2)lambda表达式在构造时, 传进去的是变量的地址,而不是具体值。只有当真正执行这个lambda表达式时,才会去确定它的值。这就是为什么上面的例子中,其结果均为3(for循环在最后,当i=2时,i又加了1)。
那么如何解决这个问题?解决方案很简单,就是在for循环中,定义一临时变量tmpNum,存储i的值即可。因为编译器会对该临时变量重新分配内存,这样,每次循环,都重新分配新的内存,就不会有这个问题了。
最后把这个“功德圆满”的解决方案贴出来:
using&Susing&System.Collections.G
using&System.L
namespace&MyCsStudy
&&&&class&Program
&&&&&&&&static&void&Main(string[]&args)
&&&&&&&&&&&&List&Func&int&&&list&=&new&List&Func&int&&();
&&&&&&&&&&&&for&(int&i&=&<span STYLE="CoLor: #;&i&&&<span STYLE="CoLor: #;&i++)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&int&tmpNum&=&i;&//临时变量
&&&&&&&&&&&&&&&&list.Add(()&=&&tmpNum);
&&&&&&&&&&&&}
&&&&&&&&&&&&foreach&(var&item&in&list)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&Console.WriteLine(item());
&&&&&&&&&&&&}
好了,Lambda表达式先学到这里,多读多写熟练就不害怕了,继续学习去也。
C#2.0的匿名方法允许我们以内联的方式来实现委托,而c#3.0的Lambda表达式允许我们使用一种更加接近人的思维,更加自然的方式来实现类似匿名方法的方式。计算机的发展告诉我们,人们对计算机上的研究都是不断在趋近于人的思维,而不是计算机的思维,比如我们已开始使用的汇编语言,然后出现了高级语言,面向对象的高级语言,等等。如何让计算机能够理解普通人的需求,我们程序员的作用就是起这种桥接作用,我们要不断的尝试让计算机更好的理解编成人员的思想。计算机能理解的抽象层级的提高,我们程序员就能更减轻痛苦。看下边的例子:
List.FindAll(
Delegate(string s){
&&&&&&&&&&&&&
Return& s.indexof(“abc”)&0;}
List.FindAll(s=&s.indexof(“abc”)&0);
很明显,lamdba表达式更加接近人的思维,而不是象内联方法那样努力的在让计算机来理解,而lambda表达式表达的非常的自然,如果我们能以这样的方式编写程序,那么是多么的舒服。我们上边的内联方式有委托,有返回值,都是为计算机写,而不是趋近于人来思考的东西。
(参数列表)=&表达式或者语句块
(x,y)=〉x*y
其实编译器会将Lambda表达式在编译的时候转化成委托类型。
Lambda表达式和委托类型
Lambda表达式L可以被转化为委托类型D,需要满足:
L和D拥有相同的参数个数。
L的参数类型与D的参数类型相同,主要隐式类型要参与类型辨析。
D的返回类型与L相同,无论L是表达式,还是语句块。
比如x=〉x*10的委托类型就是 delegate int MyDeg(int)
我们有下边的例子:
表达式MyClass.Process((x,y)=&x*y)就等同于下边的一段代码:
MyDletegate md1=new MyDelegate1(XXXXX);
MyClass.Process(md1);
Public static int bool XXXXX(int x,int y)
&&& Return
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。java成神之路---Lambda表达式 - 简书
java成神之路---Lambda表达式
标签(空格分隔):java
Lambda表达式是java8的重要更新,Lambda表达式的目标类型必须是函数式接口
什么样的接口符合函数式接口呢?
通俗直观的可这样认为:一个接口中只含有一个抽象方法。
注:函数式接口可以包含多个默认方法,类方法,但只能声明一个抽象方法。
如何使用呢?两个条件:
1.Lambda表达式的目标类型必须是明确的函数式接口
2.lambda表达式只能为函数式接口创建对象。(只能为只有一个抽象方法的接口创建对象)
Lambda表达式时为了让我们只关注方法的形参和方法体,不用关注方法名和接口或类名,当然如果这个方法的返回值为void的话,也不用关注返回值,对于有返回值的函数式接口,如果方法体一条语句就返回,同时也可以不用带方法体,直接在-&后面跟上表达式结果就会默认认为是返回值;
//常规写法:
iter.forEachRemaining(new Consumer&Student&() {
public void accept(Student t) {
System.out.println(t.getName());
//Lambda式写法:
iter.forEachRemaining((Student studnet)-&{
System.out.println(studnet.getName()));
//当只有一个类型的形参或者一个语句时,我们可以省略形参类型和方法体
iter.forEachRemaining(t-&System.out.println(t.getName()+"第一个"));
什么,一个例子不够?,那再来一个:
//常规写法:
pr.precess(target,new Command(){
public int process(int[] temp){
int sum =0;
for(int t:temp){
//Lambda式写法:
pr.process(tar,(int[] temp)-&{
int sum =0;
for(int t:temp){
如果方法体中的表达式只有一个,而且表达式的值就是返回值,甚至可以省略return语句
pr.test((a,b)-&a+b);
是不是十分简洁呢?
下面说一下注意事项:为了保证Lambda表达式的目标类型是一个明确的函数式接口,可以有下面三种常见方式:
1.将Lambda赋值给函数式接口类型的变量;
2.将Lambda表达式作为函数式类型接口的某个方法传递给某个方法。
3.使用函数式接口对Lambda式进行强制类型转换。
Object obj = (Runnable)()-&{
for(int i =0 ; i& 100 ; i++){
System.out.println(i);
当然简洁的同时,也是一把双刃剑,同时也增加了代码理解的复杂度,使用还需根据需要。
总有一些事用什么语言都不好表达,而我们希望用程序把它表达出来。}

我要回帖

更多关于 花样排球12百度云资源 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信