A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

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
版权声明:本文为博主原创文章,转载请附上博文链接!

2 个回复

倒序浏览
回复 使用道具 举报
~(。≧3≦)ノ⌒☆
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马