精华内容
下载资源
问答
  • 后来就弄了一个for循环,循环每1行,然后对每一行使用.apply()方法调用lambda函数进行转换,数据就正常显示,虽然用循环感觉比较笨,但还是开心,解决了问题。毕竟现在电脑配置那么高,不太需要考虑程序效率,能把...

    我有一个应用,需要使用pandas去mysql数据库里用pd. read_sql方法读取数据,进行一定处理后通过数据可视化组件Pyecharts在网页上进行可视化展示,图形为折线图,在显示时发现有些系列(series)的值不显示,查看pyecharts网页端的JavaScript脚本代码,发现Series的值都显示为null,后来查了资料,发现是pandas的数值类型有些跟pyecharts不兼容,pyecharts官网是这么说的:

    Note: 在使用 Pandas&Numpy 时,请确保将数值类型转换为 python 原生的 int/float。比如整数类型请确保为 int,而不是 numpy.int32

    在网上查了很多资料,比如直接使用df.astype(‘int’)对整个数据表进行转换,或者编写自定义函数然后调用df.apply()方法,都是报错,因为我的pandas原始数据里面有int,object等不同的数据类型,不能直接转换。后来就弄了一个for循环,循环每1行,然后对每一行使用.apply()方法调用lambda函数进行转换,数据就正常显示,虽然用循环感觉比较笨,但还是开心,解决了问题。毕竟现在电脑配置那么高,不太需要考虑程序效率,能把问题解决就行了。

    核心代码如下:

    #从数据库读取数据
    df=pd.read_sql(sql=sql,con=conn,index_col="日期",coerce_float=False)
    #折线图
    line = Line(init_opts=opts.InitOpts(width="1200px",height = "600px"))
    line.add_xaxis(df.columns.tolist())        #一定要加tolist()方法,不然会没有任何内容。
    
    #设置Y轴反转,X轴朝下,不用对其零值
    yaxis_opts=opts.AxisOpts(is_inverse= True,is_show=True,axisline_opts=opts.AxisLineOpts(is_on_zero=False)))
    
    for i in range(0,df.shape[0],1):            #轮循df里的所有行,添加到折线图。
      series_name = df.iloc[i].name   #系列名称
      y_axis_value=df.iloc[i].apply(lambda x: x.astype('float') if x is not None else x)    #这里把所有非空值强行转换为float
      line.add_yaxis(series_name=series_name, y_axis=y_axis_value,label_opts=opts.LabelOpts(is_show=True),
            linestyle_opts=opts.LineStyleOpts(width=2),)
            #添加Y轴数据
    
    展开全文
  • ORM框架在删除数据方面一直有个尴尬,那就是无法通过指定条件批量删除数据(当然这本不是ORM的问题,只是使用上感觉不方便)。于是对于一些删除操作,我们不得不写SQL语句或者执行存储过程,例如: ItemDataContext...
    ORM框架在删除数据方面一直有个尴尬,那就是无法通过指定条件批量删除数据(当然这本不是ORM的问题,只是使用上感觉不方便)。于是对于一些删除操作,我们不得不写SQL语句或者执行存储过程,例如:

    ItemDataContext db = new ItemDataContext();
    db.ExecuteCommand(
        "DELETE FROM Item WHERE [CreateTime] < {0}",
        DateTime.UtcNow.AddMonths(-1));

      我始终认为,在程序里出现直接的SQL语句是一件很丑陋的事情。在我看来,数据库操作应该被封装起来,而对于应用层的开发人员来说,眼中应该只有对象——退一步的话也可向数据库发送指令(就是使用存储过程)。当然,这是理想状态,值得追求,但不可强求。幸运的是C# 3.0所拥有的强大特性足以让我们对LINQ to SQL的功能进行扩展。为了更好地进行项目开发,以及周五的一次技术交流,我为LINQ to SQL扩展了批量删除功能。当项目中引用了这个扩展之后,我们就可以使用如下的代码来实现上面的功能了:

    ItemDataContext db = new ItemDataContext();
    db.Items.Delete(item => item.CreateTime < DateTime.UtcNow.AddMonths(-1));

      当然,扩展还支持更复杂的删除条件,例如:

    ItemDataContext db = new ItemDataContext();
    db.Items.Delete(item =>
        item.CreateTime < DateTime.UtcNow.AddMonths(-1) ||
        item.ViewCount < item.CommentCount && item.UserName != "jeffz"); 

      之前我对于LINQ to SQL的扩展大都基于DataContext,不过很明显,这次的扩展是基于Table的。总的来说,这个扩展比我想象中要简单不少。针对LINQ的扩展最麻烦的地方就在于解析表达式树(Expression Tree),而这个扩展关键的就是二元表达式(BinaryExpression),除了这点就没有太大问题了——当然,这也是因为我放弃了对于复杂表达式树的解析,例如现在就不支持“item.Introduction.Length < 10”这种条件,而对于更完整的解析方式来说,应该将其转化为T-SQL中的LEN函数。

      这个扩展的关键在于根据表达式树生成Where Condition,我使用三个步骤完成这个扩展,大家可以关注代码里的相关实现(如果需要的话我也可以在以后进行说明):

    1. 使用PartialEvaluator将表达式中的常量直接计算出来(例如“3 * 3”表达式将被替换为“9”),同时也会将一些存储在变量中的值使用常量进行替换。
    2. 使用ConditionBuilder将表达式中的常量收集起来,并生成带参数的Condition表达式(例如“[CreateTime] < {0} AND [UserName] <> {1}”)。
    3. 使用DataContext.ExecuteCommand方法执行完整的SQL语句。

      有了批量删除的功能,那么还缺点什么呢?那自然就是批量更新的功能了。批量更新的功能比删除略为复杂一些,我正在开发之中。在有了这个扩展之后,我们就可以使用如下的方法进行批量更新了:

    ItemDataContext db = new ItemDataContext();
    db.Items.Update(
        item => new Item
        {
            Introduction = item.Title + "Hello World",
            ViewCount = item.ViewCount + 1,
        }, // 更新方式
        item => item.CommentCount > 100 /* 更新条件 */);

      您可以点击这里下载我对批量删除的扩展。

    本文的英文版本

    来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/552044/viewspace-434516/,如需转载,请注明出处,否则将追究法律责任。

    转载于:http://blog.itpub.net/552044/viewspace-434516/

    展开全文
  • 最近要做一个初始版的数据仓库项目,有一大批的MYSQL基础数据要通过整合后写入到ES,有部分数据量非常庞大,单线程批量写入会耗时很久,就想到了使用线程池来多线程做写入操作。 这个写法不要局限于我这个应用场景...

    最近要做一个初始版的数据仓库项目,有一大批的MYSQL基础数据要通过整合后写入到ES,有部分数据量非常庞大,单线程批量写入会耗时很久,就想到了使用线程池来多线程做写入操作。

    这个写法不要局限于我这个应用场景,别的应用场景也可以修改一下里面的逻辑。

    java版本要求在 1.8以上

    附代码:

    import org.apache.commons.collections.CollectionUtils;
    
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * 批量多线程执行写入任务
     */
    public class BatchThreadSave {
    
        /**
         * 批量多线程执行写入任务
         * @param action 返回的截取数据表  自行写操作方法
         * @param dataList 总数据表
         * @param threadCount 需要的线程总数  0 < threadCount < 11
         * @param <F> 指定数据表泛型
         */
        public static <F> void save(Executor<? super List<F>> action, List<F> dataList, int threadCount) {
            if (CollectionUtils.isEmpty(dataList)) {
                return;
            }
            if (threadCount < 1 || threadCount > 10) {
                return;
            }
            int threadSize = dataList.size() / (threadCount - 1);
            // 总数据条数
            int dataSize = dataList.size();
            // 分段数
            int threadNum = dataSize / threadSize + 1;
            // 创建一个线程池
            ExecutorService exec = Executors.newFixedThreadPool(threadCount);
            // 定义一个任务集合
            List<F> cutList = null;
            // 确定每条线程的数据
            try {
                for (int i = 0; i < threadNum; i++) {
                    if (i == threadNum - 1) {
                        cutList = dataList.subList(threadSize * i, dataSize);
                    } else {
                        cutList = dataList.subList(threadSize * i, threadSize * (i + 1));
                    }
                    List<F> finalCutList = cutList;
                    exec.execute(() -> {
                        action.runAction(finalCutList);
                    });
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 关闭线程池
                exec.shutdown();
            }
        }
    
        public interface Executor<T extends List> {
            void runAction(T t);
        }
    
    
    
    
    }

    那该怎么用呢?

    public void buildUserIndex() {
            List<User> users = userMapper.findAll();
            log.info("共获取到用户:" + users.size());
    
            BatchThreadSave.save(finalCutList -> {
                int j = 0;
                for (User user : finalCutList) {
    
                    j++;
                    log.info(Thread.currentThread().getName() + "   当前执行到" + user.getId() + "  剩余:" + (finalCutList.size() - j));
    
                    //finalCutList 这里就是被截取后的数据, 只管写后面的实现
                    //这里执行你的业务逻辑就行了  比如保存  数据处理等等
                    
                    
                }
            }, users, 10);
    
        }

     

    展开全文
  • Lambda表达式

    2020-05-03 21:18:10
    慕课网Lambda笔记 第一章 Java为什么引入 Lmabda表达式 1.1 什么是Lambda表达式 Lambda表达式也被成为箭头函数、匿名函数、闭包 Lambda表达式体现的是轻量级函数式编程思想 ‘->’符号是Lambda表达式的核心符号...

    慕课网Lambda笔记

    第一章 Java为什么引入 Lmabda表达式

    1.1 什么是Lambda表达式

    Lambda表达式也被成为箭头函数、匿名函数、闭包
    Lambda表达式体现的是轻量级函数式编程思想
    ‘->’符号是Lambda表达式的核心符号,符号左侧是操作参数,符号右侧是操作表达式

    1.2 Model Code as Data

    Model Code as Data,编码及数据,尽可能轻量级的将代码封装成数据。
    解决方案:接口&实现了(匿名内部类)
    存在问题:语法冗余、this关键字、变量捕获、数据控制等

    1.3 功能接口的设计及优化

    传统模式下新线程的创建
    传统模式下新线程的创建
    使用jdk1.8 新特性 lmabda表达式来优化线程模式
    在这里插入图片描述

    1.4 为什么要使用 Lmabda表达式

    1.它不是解决未知问题的新技术
    2. 他是对现有解决方案上语义的优化。
    3. 需要根据实际需求考虑性能问题。

    第二章 函数式接口的概述和定义

    2.1函数式接口定义

    函数式接口(functuon interface),就是Java类型系统中的接口
    函数式接口,是只包含一个接口方法的特殊接口
    语义化检测注解:@FunctionAllnterface,用来检查函数式接口的合法性

    在这里插入图片描述在这里插入图片描述
    定义一个函数式接口只需要在接口中提供一个接口方法,并在接口上添加@FunctionAllnterface注解即可,如果添加了多个饿方法,@FunctionAllnterface就会报错

    2.2默认方法和静态方法

    2.2.1默认接口方法的特性

    以当前用户身份接口为例,创建一个实现类 返回用户的身份
    在这里插入图片描述
    对当前代码进行测试
    在这里插入图片描述
    以上代码当需求进行变动后,比如要求所有的用户验证可以同时获取用户的验证信息【是否认证成功|成功-返回用户|失败-返回null】时,我们就需要修改所有的实现类代码。这时Lambda表达式可以解决这个问题,我们可以在接口中声明一个默认方法
    在这里插入图片描述
    这样我们就可以直接通过代码来调用默认方法
    在这里插入图片描述

    2.2.2 静态接口方法的特性

    以消息发送接口为例,在接口中添加一个静态方法:验证消息格式是否合法
    加粗样式
    添加一个实现类,重写接口中的方法
    在这里插入图片描述
    在format方法中,我们只是打印了一句话 消息转换。。。,并返回了msg,这时候我们可以直接调用接口的静态方法来验证消息的合法性。通过执行结果可以看出,静态方法不会对函数式接口的语义也不会产生影响,默认接口,函数式接口,静态接口可以在一个接口类中同时存在。

    从Object中继承的方法不会影响函数式接口

    由于java中的类都直接的或者间接的继承了Object类,所以 从Object继承的方法,无论是否是抽象的,都不会影响你函数式接口的语义。例如,在 IMessageFormat 中添加一个来自object的方法 toString(),函数式接口是不会报错的
    在这里插入图片描述

    2.2.3Lambda表达式和函数式接口的关系

    Lambda 只能操作一个方法 Java 中的Lambda表达式就是一个函数式接口的实现

    实现接口方法的另一种方式是使用匿名内部类,通过使用匿名内部类的方式来实现用户权限的验证操作。
    在这里插入图片描述
    执行结果:
    在这里插入图片描述
    通过观察匿名内部类和前面的实现方式,都会发现,其实和数据相关的代码只有
    " return “admin”.equals(username) ? “超级管理员” : “普通会员”; " 这一行,其他的代码都是冗余代码,那么能不能对代码进行优化呢?这就要使用到JDK8中的Lambda表达式。
    在这里插入图片描述
    相比较前面的匿名内部类,Lambda表达式实现方式更为简洁
    执行结果:
    在这里插入图片描述

    2.2.4 JDK 中常见的函数式接口

    Java类型系统内建函数式接口

    在这里插入图片描述

    JDK8提供了java.util.function包,提供了常用的函数式功能接口

    1.java.util.function.Predicate
    接收参数对象T,返回一个boolean类型结果,适合需要判断的场景
    在这里插入图片描述
    执行结果:
    在这里插入图片描述
    2.java.util.function.Comsumer
    接收参数T,不反回结果

    在这里插入图片描述
    执行结果:
    在这里插入图片描述
    3. java.util.function.Function<T,R>
    接收一个参数对象T,返回结果对象R

    在这里插入图片描述
    执行结果:
    在这里插入图片描述
    4. java.util.function.Supplier
    不接受参数,提供T对象的创建工厂

    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    常见的函数式接口使用

    5. java.util.function.UnaryOperator
    接收参数对象T,返回结果对象T ,常用于适配器模式

    在这里插入图片描述
    执行结果:
    在这里插入图片描述
    6. java.util.function.BinaryOperator
    接收两个T对象,返回一个T对象的结果(使用场景:例如对两个对象进行比较,返回较大的结果)

    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    总结:

    java.util.function提供了大量的函数式接口
    Predicate 接收参数对象T,返回一个boolean类型结果
    Comsumer 接收参数T,不反回结果
    Function 接收一个参数对象T,返回结果对象R
    Supplier 不接受参数,提供T对象的创建工厂
    UnaryOperator 接收参数对象T,返回结果对象T
    BinaryOperator 接收两个T对象,返回一个T对象的结果

    2.2.5 Lmabda表达式的基本语法

    			>1)声明:就是 Lambda表达式绑定的接口类型
                2)参数:包含在一对圆括号中,和绑定的接口中的抽象方法中的参数顺序一致。
                3)操作符:->
                4)执行代码块:包含在一对大括号中,出现在操作符的右侧
                 [接口声明] = (参数) ->{执行代码}
    
    没有返回值的Lambda表达式

    在这里插入图片描述
    如果在执行代码块中,只有一行代码,大括号是可以省略的
    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    带有参数 但是没有返回值得Lambda 表达式和接口

    带有参数时,要将参数写在小括号中,参数的顺序和接口中定义的顺序相同
    在这里插入图片描述
    在设置参数时,也可以不写参数的类型,JVM会自动推断出参数的类型,以下方式和上面的代码是一样的
    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    带有参数,带有返回值得Lambda表达式

    在这里插入图片描述
    当花括号内只有一行代码时,可以不添加花括号,同时,也不需要添加 return 关键字,虚拟机会自动帮你返回
    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    总结

    1 Lambda 表达式,必须和接口进行绑定
    2 Lambda 表达式的参数,可以附带0到n个参数,括号中的参数类型可以不用指定,JVM在运行时,会自动根据绑定的抽象方法进行推导
    3 Lambda 表达式的返回值,如果代码快只有一行并且没有大括号,不用写大括号,单行代码会自动返回,如果添加了大括号,或者代码有多行代码,必须通过return 关键字返回结果

    3.6变量访问

    匿名内部类中的变量访问

    在这里插入图片描述

    lamdba表达式对于变量的访问

    在这里插入图片描述

    Lambda表达式类型检查

    表达式类型检查

    定义一个函数式接口 MyInterface,接收两个范型R,T,并提供一个方法 strategy 接受参数T 返回参数R
    在这里插入图片描述
    定义一个方法test,接受一个Myinterface作为参数,范型为String 和List,在方法内部我们将String 添加到List集合中
    在这里插入图片描述
    分别使用匿名内部类 和Lambda表达式的方式调用test
    在这里插入图片描述
    在Lambda表达式的写法中,并没有指明方法的参数为Myinterface,而是直接传递了参数X,y,这是由底层虚拟机来自动推导出来的。

    执行结果
    在这里插入图片描述

    总结

    当我们使用Lambda表达式语法的时候,jvm会获取当前方法的参数来进行推导,从而自动为我们绑定方法的参数类型.这就是Lambda表达式的类型检查

    3.7方法重载和Lambda表达式

    首先创建一个类App4,在App4中创建两个接口 Parame1 和Parame2,并定义outInfo(String info) 方法
    在这里插入图片描述
    然后定义重载方法lambdaMethod,参数分别是Parame1和Parame2
    在这里插入图片描述
    使用传统的匿名内部类的方式调用,在main方法中创建App4的对象,使用对象点lambdaMethdo的方式new一个Parame1或者Parame2
    在这里插入图片描述
    执行结果:
    在这里插入图片描述
    使用lambda表达式的话因为是重载方法,jvm自动推导类型的时候类型检查不通过,会报如下错误
    在这里插入图片描述
    在这种情况下只能使用匿名内部类来替代lambda表达式

    3.8深入理解Lambda表达式

    3.8.1Lambda表达式低层解析运行原理

    创建一个类App,并创建一个用于Lambda表达式执行的函数式接口IMakeUP,提供一个方法makeUp(String msg),在main方法中创建Lambda表达式打印msg
    在这里插入图片描述
    编译后,我们可以看到生成了App.class文件和IMakeUP.class文件
    在这里插入图片描述
    通过使用 javap -p App.class 命令对class文件进行反编译得到结果
    在这里插入图片描述
    Lambda表达式在JVM低层解析成私有静态方法和匿名内部类型

    通过实现接口的匿名内部类型中接口方法调用静态实现方法,完成Lambda表达式的执行

    第四章 Lambda表达式在集合中的运用

    4.1 方法引用

    • 方法引用是结合Lambda表达式的一种语法特性,

    首先创建一个测试类Test, 在里面创建一个内部类Person,添加属性 name(名字),gender(性别),age(年龄),并使用lombok创建get/set方法和构造函数
    在这里插入图片描述

    • 静态方法引用

    原始方式 类型名称.方法名称() -->类型名称::方法名称
    初始化一些数据,并对数据进行排序
    在这里插入图片描述
    使用匿名内部类的方式进行排序
    在这里插入图片描述
    执行结果:
    在这里插入图片描述
    Lambda表达式的实现方式
    在这里插入图片描述
    执行结果:
    在这里插入图片描述
    静态方法引用

    在Person类中添加一个静态方法comperByAge
    在这里插入图片描述
    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    • 实例方法引用

    创建类型对应的对象 -->对象引用::实例方法名称

    在Test下创建一个新类PersonUtils,添加一个方法comerByName(),根据人员的名称的hash值来进行排序
    在这里插入图片描述
    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    • 构造方法引用

    构造方法的引用需要绑定一个函数式接口

    首先创造一个函数式接口
    加粗样式
    在这里插入图片描述

    4.2 Steam概述

    什么是Steam
    Steam是Java为了操作数组,集合来进行复杂的聚合操作而推出的一套新的API
    新创建一个测试类Test2 创建一个main方法,在main方法中初始化一个字符串集合

    1.要求长度大于等于五的内容为有效账号
    在这里插入图片描述
    循环方式:
    在这里插入图片描述
    迭代器方式
    在这里插入图片描述
    使用Steam结合Lambda表达式的方式
    在这里插入图片描述
    注意:这三种方式的性能是相同的,只是精简了代码长度

    4.3 SteamAPI

    4.3.1Steam聚合操作

    什么是聚合操作?

    在常规业务处理中,针对业务的批量操作,例如,在电商项目中 ,获取指定数据的年平均消费额,获取指定店铺中最便宜的商品,获取指定店铺的当月有效订单数量等等

    Steam的处理流程
    获取数据源->数据转换(可以执行一次或者多次)->获取结果

    4.3.2获取Steam对象

    从集合,数组中获取

    Collection.steam(),如上一节中的account.steam(); //从集合中获取Steam对象
    Collection.parallelSteam(); //获取到一个支持并发的Steam对象;
    Arrs.Stream(T t); //从数组中获取Stream对象

    从缓冲流中获取

    BufferReader
    BufferReader.lines()->stream();

    静态工厂

    java.util.stream.Intstream().range()…
    java.nio.file.Files.work()…

    自行构建

    java.util.Spliterator

    更多的方式

    Random.ints()
    Pattern.splitAsStream()…

    4.3.3 Stream操作类型

    Stream的操作类型主要分为两种主要类型和一种辅助类型

    中间操作API

    API:intermediate中间:记录操作[无状态|有状态]

    它的操作结果是一个Stream对象,中间操作可以有一个或者多个连续的中间操作.

    需要注意的是,所有的中间操作,只记录操作方式,不做具体执行,直到结束操作执行时,才做数据的最终执行.中间操作就是业务的逻辑处理

    中间操作的过程分为有状态和无状态的操作.

    无状态: 数据处理时,不受前置中间操作的影响,就是前面的中间操作不会对当前的中间操作产生影响.
    无状态API:
    map
    filter
    peek
    parallel
    sequential
    unordered

    有状态: 数据处理时,会受到前一个中间操作的影响.
    例如,前一个中间操作是一个排序操作,当前中间操作是一个截取操作,有状态下,当前操作会对排序后的结果进行截取.
    有状态API:
    distinct
    sorted
    limit
    skip

    结束操作(终结操作)(Terminal)

    一个Stream只能有一个终结操作,一旦执行终结操作,Stream就会真实处理数据,生成对应的处理结果,并且这个结果是不可逆的…
    终结操作又区分为:短路和非短路操作. 短路操作和非短路操作是根据处理结果来定义的

    非短路操作:Stream对象必须处理完集合中所有的数据,才能返回处理结果
    非短路操作API:
    forEach
    forEachOrdered
    toArray
    reduce
    collect
    min
    max
    count
    iterator

    短路操作:当前的Strame对象在处理过程中,一旦满足某个条件,就可以获取结果,并不需要处理所有的数据
    短路操作API:
    anyMatch
    allMatch
    noneMatch
    findFirst
    findAny等
    短路操作也被称作:Short-circuiting.
    什么时候使用短路操作:
    例如从一个无限大的Stream中返回一个有限大的Stream

    4.4 Steam操作集合中的数据

    4.1.1将多个数据转换为Stream对象

    多个数据转换得到Stream对象

    在这里插入图片描述

    数组转换Stream对象

    在这里插入图片描述

    列表转换Stream对象

    在这里插入图片描述

    集合操作

    在这里插入图片描述

    Map操作

    在这里插入图片描述

    4.1.2Stream 对于基本数据类型的功能性封装

    针对于基本数据类型Strame在运算时会进行频繁的装箱拆箱,所以对于基本数据类型进行功能性封装
    只针对于常用的 int lang double 类型 ,其他的没有

    以int为例
    在这里插入图片描述

    4.1.3Stream转换得到指定的数据类型(数组,集合,字符串,map)

    数组

    在这里插入图片描述

    字符串

    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    列表

    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    集合

    在这里插入图片描述
    >执行结果:
    在这里插入图片描述

    Map

    在这里插入图片描述
    执行结果:
    在这里插入图片描述
    在这里,Collectors.toMap方法需要传入一个Function,这个接口在处理的过程中会得到两个不同的数据 ,由于我们的stream
    中只包含了一个单个数据,所以我们在处理的过程中需要将Map中的数据进行单独的处理

    在这里插入图片描述

    注意:由于stream一旦进行终结操作,那么久意味着整个过程的结束,所以上述代码无法一次性全部执行,只能在执行一个的时候,将其他代码注释掉.

    4.1.4 Stream常见的API操作

    准备数据

    在这里插入图片描述

    在每个数据的前面增加一个字段,梁山好汉

    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    添加过滤条件,来过滤符合条件的用户

    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    循环遍历

    在这里插入图片描述

    使用peek来进行多次的迭代操作

    在这里插入图片描述
    通过peek可以对数据进行多次的迭代操作,由于peek是中间操作,所以在peek的过程中不会遍历数据,只有等到执行终结操作的时候才会处理数据,所以虽然进行了三次peek,但实际上只进行了一次迭代操作.

    stream对于数字运算的支持

    构建数据

    在这里插入图片描述

    skip()

    skip操作是一个中间操作,他是一个有状态的操作 跳过部分数据,完成数据的提取

    在这里插入图片描述
    执行结果
    在这里插入图片描述

    limit()

    limit 操作是一个中间操作,他是一个有状态的操作 限制输出数据的输出数量

    先跳过3个数据在限制输出两个数据
    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    distinct()

    distinct 操作是一个中间操作,他是一个有状态的操作 去除重复数据

    在这里插入图片描述
    执行结果:
    在这里插入图片描述
    初始化数据的时候忘了加重复元素…所以这的结果和原来的数据一样 emmmm…

    sorted()

    sorted 操作是一个中间操作,他是一个有状态的操作 对数据进行排序

    x-y是从小到大排序, y-x是从大到小排序
    在这里插入图片描述
    执行结果
    在这里插入图片描述

    max()

    max 操作是一个中间操作,他是一 个有状态的操作 获取最大值

    如果改变了x-y的顺序的话得到的结果也会改编.调用max后会返回一个Optional对象,调用Optional.get()即可获取结果
    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    min()

    minx 操作是一个中间操作,他是一个有状态的操作 获取最小值

    如果改变了x-y的顺序的话得到的结果也会改编.调用min后会返回一个Optional对象,调用Optional.get()即可获取结果
    在这里插入图片描述
    执行结果
    在这里插入图片描述

    reduce()

    reduce 操作是一个中间操作,他是一个有状态的操作 合并处理数据

    这里对数据做了一个累加,即前面的数据想加合并,然后在与下一个数据想加调用reduce后会返回一个Optional对象,调用Optional.get()即可获取结果,这里直接使用方法链调用了
    在这里插入图片描述
    执行结果:
    在这里插入图片描述

    5 Lambda表达式在实际生产中的应用

    5.1Lambda表达式重构项目

    5.2 Lambda和Stream的性能问题

    1 通过基本数据类型:整数进行测试
    创建一个Integer list 集合,添加一些随机数集合数据
    在这里插入图片描述

    性能测试
    1 stream 对象

    创建一个方法testStreame 接收一个list集合方法,通过stream对象获取最大值
    在这里插入图片描述
    执行时间 : 641ms
    在这里插入图片描述

    2.for循环

    创建一个方法testForloop 接收一个list集合方法,通过stream对象获取最大值
    在这里插入图片描述
    执行时间:94 ms
    在这里插入图片描述

    3 parallelstream

    创建一个方法testParallelstream 接收一个list集合方法,通过stream对象获取最大值在这里插入图片描述
    执行时间: 169ms
    在这里插入图片描述

    4 增强型for循环
    创建一个方法testStrongstream 接收一个list集合方法,通过stream对象获取最大值![在这里插入图片描述](https://img-blog.csdnimg.cn/20200503202317431.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NjEyNzU1,size_16,color_FFFFFF,t_70)
    执行时间:83 ms
    

    在这里插入图片描述

    5 迭代器操作

    创建一个方法testIterator接收一个list集合方法,通过stream对象获取最大值
    在这里插入图片描述
    执行时间: 74ms
    在这里插入图片描述

    总结:串行的Stream 的执行时间比较长,并行的Stream和增强for很接近了,\

    2 通过复杂数据类型:对象进行测试

    创建一个对象产品.并增加一个全属性的构造方法
    在这里插入图片描述
    我们来测试获取热度最高的产品对象

    创建一个对象集合,并初始化数据
    在这里插入图片描述

    通过五种方式对获取热度最高的产品进行测试
    1 Stream

    在这里插入图片描述执行时间 :380ms
    在这里插入图片描述

    2 parallelstream

    在这里插入图片描述
    执行时间:90ms
    在这里插入图片描述

    3 for

    在这里插入图片描述
    执行时间:110ms
    在这里插入图片描述

    4 增强for

    在这里插入图片描述
    执行时间85ms’
    在这里插入图片描述

    5迭代器

    在这里插入图片描述
    执行时间 70ms
    在这里插入图片描述
    总结:在处理对象的过程中,串行Stream 依旧是执行时间最长的,parallelstream的处理事件已经可以和迭代器媲美,比普通的for要高,最快的还是迭代器.和增强for

    5.3 Stream 的线程安全问题
    1 Stream并行原理

    在这里插入图片描述
    通过整数列表的并行复制来测试Stream是否存在安全问题
    初始化一个整数集合,分别通过串行Stream和并行Stream来进行集合间的复制,并打印源集合和复制后的集合的长度
    在这里插入图片描述
    执行结果:
    在这里插入图片描述
    源数据长度为1000,串行的Stream的长度没变,但是并行的Stream的集合长度变小了.说明并行Stream存在线程安全问题.

    展开全文
  • 目录 介绍——Java 8 第一部分——Java中的Lambda表达式 第二部分——默认方法 第三部分——批量数据操作 总结——TL;DR
  • Java Lambda

    2018-04-08 14:49:26
    简介Lambda作为函数式编程中的基础部分,在其他编程语言(例如:Scala)中早就广为使用,但在Java领域中发展较慢,直到java8,才开始支持Lambda。抛开数学定义不看,直接来认识LambdaLambda表达式本质上是匿名方法...
  • Lambda Expression

    2019-04-26 19:08:00
    Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包...
  • lambda 03

    2019-01-10 18:55:38
    为引入Lambda表达式,Java8新增了java.util.funcion包,里面包含常用的函数接口,这是Lambda表达式的基础,Java集合框架也新增部分接口,以便与Lambda表达式对接。 首先回顾一下Java集合框架的接口继承结构: 上...
  • 我要通过Id对应去修改Name值,下面这条sql语句能转吗?谢谢 <code class="language-sql">UPDATE test SET name = CASE id WHEN 1 THEN 'Name1' WHEN 2 THEN 'Name2' WHEN 3 ...
  • IEnumerable<Rect> rectlist3 = rectlist.Select(rect =>newRect(rect.X + 2000, rect.Y, rect.rect.Width, rect.rect.Height)); 转载于:https://www.cnblogs.com/gaoxianzhi/p/4084328.html
  • Lambda架构

    2021-09-28 09:10:36
    例如:HDFS可以对大规模的数据进行批量计算,但批计算延迟很高。所以,如果要做一些低延迟的数据操作,是无法考虑直接使用HDFS的。 而NoSQL(就像Cassandra)提供了更简单的数据模型(key、value模型)以实现高度可...
  • Lambda简介

    千次阅读 2016-10-25 17:55:09
    Lambda作为函数式编程中的基础部分,在其他编程语言(例如:Scala)中早就广为使用,但在Java领域中发展较慢,直到java8,才开始支持Lambda。 抛开数学定义不看,直接来认识LambdaLambda表达式本质上是匿名方法...
  • Java Lambda表达式

    2020-12-17 14:33:26
    Java Lambda表达式的一个重要用法是简化某些匿名内部类(Anonymous Classes)的写法。实际上Lambda表达式并不仅仅是匿名内部类的语法糖,JVM内部是通过invokedynamic指令来实现Lambda表达式的。具体原理放到下一篇。...
  • Lambda - 表达式

    千次阅读 2018-06-11 14:37:58
    为了编写这类处理批量数据的并行类库,需要在语言层面上修改现有的 Java:增加 Lambda 表达式。面向对象编程是对数据进行抽象,而函数式编程是对行为进行抽象。在写回调函数和事件处理程序时,程序员不必再纠缠于...
  • Java Lambda 表达式。

    2020-07-27 22:54:57
    Java Lambda 表达式。 文章目录Java Lambda 表达式。~ ~
  • Java中Lambda表达式的使用

    万次阅读 多人点赞 2019-03-26 17:39:22
    Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。...
  • Lambda学习心得

    2019-06-06 10:15:32
    Lambda学习心得Lambda简介Lambda语法Lambda用在哪里Lambda方法引用1. 静态方法引用2. 实例方法引用3. 构造方法引用Lambda的域以及访问限制访问局部变量Lambda不能访问函数接口的默认方法Lambda实践Predicate接口...
  • Lambda表达式浅析

    2018-12-18 10:32:00
    Lambda表达式浅析
  • Lambda架构简介

    2021-03-02 10:54:04
    参考文章:深入理解大数据架构之——Lambda架构 传统系统的问题 “我们正在从IT时代走向DT时代(数据时代)。IT和DT之间,不仅仅是技术的变革,更是思想意识的变革,IT主要是为自我服务,用来更好地自我控制和管理...
  • 批量修改4.0

    2021-10-03 00:57:43
    4.0 1.修复了之前因文件重名而导致文件名修改时文件被删除的bug。 2.
  • Lambda简单理解

    2019-10-28 17:26:41
    Collections.addAll(list,1,2,3,4,5,6);将元素批量添加进list集合中 实现comparator接口方式 list.sort(new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { ...
  • AWS Lambda 常见问题

    千次阅读 2019-05-26 23:47:14
    问:什么是 AWS Lambda? 通过 AWS Lambda,无需配置或管理服务器即可运行代码。您只需按消耗的计算时间付费 – 代码未运行时不产生费用。借助 Lambda,您几乎可以为任何类型的应用程序或后端服务运行代码,而且全部...
  • Lambda表达式初探

    2018-08-04 21:05:08
    Lambda表达式的本质只是一个"语法糖",由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能,Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码(将...
  • Lambda and Collections

    2019-04-25 15:11:10
    Lambda and Collections [TOC] 前言 我们先从最熟悉的*Java集合框架(Java Collections Framework, JCF)*开始说起。 为引入Lambda表达式,Java8新增了java.util.function包,里面包含常用的函数接口,这是Lambda...
  • java8_Lambda

    2020-06-27 15:48:15
    Lambda function包,提供lambda接口 public interface Function<T, R> { /** * Applies this function to the given argument. * * @param t the function argument * @return the function result */ ...
  • 最简单的Lambda入门教程

    万次阅读 多人点赞 2016-01-28 21:50:31
    Lambda简介Lambda作为函数式编程中的基础部分,在其他编程语言(例如:Scala)中早就广为使用,但在JAVA领域中发展较慢,直到java8,才开始支持Lambda。抛开数学定义不看,直接来认识LambdaLambda表达式本质上是...
  • Lambda高级操作

    2021-02-07 11:35:08
    Lambda表达式(Lambda Expression) 2.1 Lambda简介 2.1.1 概述 ​ Lambda表达式,是JDK 8的新特性,也被称为箭头函数、匿名函数、闭包;它所体现的是一种轻量级函数式编程思想;在其表达式中,“->”符号是Lambda...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,787
精华内容 3,514
关键字:

lambda批量修改