lambda学习经验分享(由邮件中copy,可以跟着思路,但不必揪其中类名不懂)
lambda的组成:
表达式分为三个部分组成 1)参数列表 2)箭头 -> 3) lambda主体
语法规则
(parameters) -> expression
(parameters) -> { statements;}
lambda学习之前你需要了解的理论知识(简单概括):
1)行为参数化:
行为参数化就是将代码块传递给另一个方法(作为方法的参数),在方法中去执行传入的代码块
2)匿名类
匿名类没有名字,它允许你同时声明并实例化一个类,优点:随时用随时创建
3)函数式接口
可以有很多默认方法,但是有且只有一个抽象方法。
4)
按照特定的业务需求,建立起符合自己业务流程的行为载体(函数式接口),和 运用该行为的逻辑代码块
学习lambda表达式,过程
第一步:明确那些行为可以对其进行行为参数
举例:Gmp(一个项目名称)中许多采取了多结果集形式,但是多结果集返回时候,我们要对其进行过滤筛选进行反序列化。
例如返回五个结果集,我们就会进行五次以下的序列化过程(这部分代码是很啰嗦的,看起来唯一不同的地方就是过滤条件不同,过滤后插入的数组不同)
下面语句目的:过滤出dbOutlet_Drawing 集合中属性 DrawingId 等于类 tempBug 中 DrawingId 的类,将其加入到tempOutboundBug
for (Entities.Entity_Drawing tempDrawing:dbOutlet_Drawing) {
if (tempBug.DrawingId.equals(tempDrawing.DrawingId)){
tempOutboundBug.BugDrawing.add(tempDrawing);
}
}
for (Entities.Entity_BugPhoto tempBugPhoto:dbOutlet_BugPhoto) {
if(tempBugPhoto.BugId.equals(tempBug.BugId)){
tempOutboundBug.BugPhotoList.add(tempBugPhoto);
}
}
第二步:使用lambda表达式进行优化(简单的优化)
dbOutlet_Drawing.forEach(tempDrawing ->{
if (tempBug.DrawingId.equals(tempDrawing.DrawingId)){
tempOutboundBug.BugDrawing.add(tempDrawing);
}
});
dbOutlet_BugPhoto.forEach(tempBugPhoto ->{
if(tempBugPhoto.BugId.equals(tempBug.BugId)){
tempOutboundBug.BugPhotoList.add(tempBugPhoto);
}
});
我们可以看见大量的for语句已经被lambda替换掉了,但是你的感觉一定是,只是外观好看了一点嘛,代码也没见得少了很多,没有必要这么写,还不好懂
那是我们还没有用好lambda这个强大的功能。
第三步: 在第一步的代码中和第二步的代码中我们应该有感觉,只是过滤条件不同,和插入的数组不同。
这时我们可以确定我们要行为参数化那些代码块,就是那些标注紫色的代码块。
开始进行行为参数化
1)明确行为参数化的签名(也就是规则,入参和出参。我们根据不同的签名来选择不同的函数式接口)
查看我们要行为参数化的代码块,明确其规则为 出参:boolean 入参:一个对象
在java8 中我们有这样一个函数式接口 Predicate ,它的入参为T泛型对象,出参为boolean 类型,里面的抽象方法为 test。我们可以让这个Predicate 接口作为我们的行为参数化的载体,传入到接下来我们定义的 规范建模的代码块中
public interface Predicate<T> {
boolean test(T t);}
按照需求规范建模
1)我们已经有了行为载体,Predicate函数式接口
2)符合业务逻辑的 运用该行为的代码逻辑块
代码前后文 :
ArrayList<Entities.Entity_Drawing> dbOutlet_Drawing= (ArrayList<Entities.Entity_Drawing>)dbResult.get(0);
ArrayList<Entities.Entity_Region> dbOutlet_Regin= (ArrayList<Entities.Entity_Region>)dbResult.get(1);
dbOutlet_Drawing.forEach(tempDrawing ->{
Outbounds.OutboundDrawing temp_OutboundDrawing = new Outbounds.OutboundDrawing();
temp_OutboundDrawing.RegionGroup = new ArrayList<>();
temp_OutboundDrawing.RegionList = new ArrayList<>();
temp_OutboundDrawing.Drawing = tempDrawing;
temp_OutboundDrawing.RegionList = filter(dbOutlet_Regin,(Entities.Entity_Region tempRegin) -> tempRegin.DrawingId.equals(tempDrawing.DrawingId));
});
运用时lambda表达式:
temp_OutboundDrawing.RegionList =
filter(dbOutlet_Regin,(Entities.Entity_Region tempRegin) -> tempRegin.DrawingId.equals(tempDrawing.DrawingId))
下面的代码块虽然使用起来简单了好多,但是只能针对Entities.Entity_Region这一个类,难道我们还要为每一个需要使用过的类
定义这样一个方法吗?答案一定是否定的,我们还需要对其进行优化。
public static ArrayList<Entities.Entity_Region> filter(ArrayList<Entities.Entity_Region> list, Predicate<Entities.Entity_Region> ){
ArrayList<Entities.Entity_Region> result = new ArrayList<>();
list.forEach(str ->{
if(p.test(str)){
result.add(str);
}
});
return result;
}
这里的优化(抽象化):将固定的对象改为泛型,这样适用的范围更广
public static <T> ArrayList<T> filter(ArrayList<T> list, Predicate<T> p){
ArrayList<T> result = new ArrayList<>();
list.forEach(str ->{
if(p.test(str)){
result.add(str);
}
});
return result;
}
第四步:进行使用啦
使用规则:对一个list进行过滤,然后将符合条件的对象数组返回
例如Region类可以使用
temp_OutboundDrawing.RegionList =
lambdaFilter.filter(dbOutlet_Regin,(Entities.Entity_Region tempRegin) -> tempRegin.DrawingId.equals(tempDrawing.DrawingId));
RegionGroup类可以使用
temp_OutboundDrawing.RegionGroup =
lambdaFilter.filter(dbOutlet_ReginGroup,(Outbounds.outbound_RegionGroup tempRegionGroup)
->tempRegionGroup.DrawingId.equals(tempDrawing.DrawingId));
Bug类可以使用
responseMarker.BugList =
lambdaFilter.filter(dbOutlet_Bug,(Entities.Entity_Bug tempBug) -> tempBug.MarkerId.equals(tempMarker.MarkerId));
所有符合我们建模规范逻辑 的类都可以使用。这样你的代码中就不会有
第一种
for (Entities.Entity_Drawing tempDrawing:dbOutlet_Drawing) {
if (tempBug.DrawingId.equals(tempDrawing.DrawingId)){
tempOutboundBug.BugDrawing.add(tempDrawing);
}
}
第二种(以为自己用了lambda,其实不然)
dbOutlet_Drawing.forEach(tempDrawing ->{
if (tempBug.DrawingId.equals(tempDrawing.DrawingId)){
tempOutboundBug.BugDrawing.add(tempDrawing);
}
});
你可以随意写
[java] view plain copy
<code class="language-java">responseMarker.BugList = lambdaFilter.filter(dbOutlet_Bug,(Entities.Entity_Bug tempBug)
responseMarker.BugList = lambdaFilter.filter(dbOutlet_Bug,(Entities.Entity_Bug tempBug) -> tempBug.MarkerId.equals(tempMarker.MarkerId));
tempOutboundBug.BugDrawing = lambdaFilter.filter(dbOutlet_Drawing,(Entities.Entity_Drawing draw) -> tempBug.DrawingId.equals(draw.DrawingId));BugPhotoList = lambdaFilter.filter(dbOutlet_BugPhoto,(Entities.Entity_BugPhoto bugPhoto) -> tempBug.BugId.equals(bugPhoto.BugId));
tempOutboundBug.BugFollowList = lambdaFilter.filter(dbOutlet_BugFollow,(Entities.Entity_BugFollow bugFollow) -> tempBug.BugId.equals(bugFollow.BugId));
tempOutboundBug.BugOperationList = lambdaFilter.filter(dbOutlet_BugOperation,(Entities.Entity_BugOperation bugOperation) -> tempBug.BugId.equals(bugOperation.BugId));</code>
总结:对于本篇文章内容可以用于过滤一个集合,并且将过滤后符合条件的结果赋值给另一个集合。这篇主要介绍了行为抽象化,
以及将方法抽象化使其应用范围更广。
其实对于一个集合的过滤没有那么麻烦,下一章将讲述用其 内置函数式接口 和 java8 的 stream(流) 来对类进行过滤。
---------------------
作者:Mark_XC
来源:CSDN
原文:https://blog.csdn.net/Mark_Chao/article/details/80685599
版权声明:本文为博主原创文章,转载请附上博文链接!
|
|