vlambda博客
学习文章列表

函数式编程_类型拆装及重载解析

朝臣待漏五更寒,

铁甲将军夜渡关。

山寺日高僧未起,

看来名利不如闲。


    一首定场消声去,醒木拍桌开书来。各位看官,别来无恙,今儿个我们聊一番函数式编程的类库。



    书归正传,让我们来探一番函数式类库地究竟。在雷记很久之前地帖子中,对于函数式地流做了一些简单的介绍,还有一些基于lambda和stream地使用的例子,让我们继续沿着这个思路搞下去。


要怎样在代码中使用lambda表达式?



    由于lambda表达式函数接口的类型可以内部推导,因此在调用角度看来,调用lambda表达式和调用普通的接口方法没有区别。让我们看一个日常处理中十分常见的场景:


    公司分派了一个新的项目下来,要处理大数据量的日志,在编码时日志框架中要设置类似void debug(String message)的方法,在判断上下文日志级别为debug时,要打印对应日志级别的日志。那么这时就会出现一个问题,要在各处判断日志级别是否为debug级别,频繁地计算判断会影响系统性能,海量的数据写入也会导致系统io占用率被打到很高。


    面对这个情况,要拆分一下问题,首先日志等级判断的频繁性,其次是海量日志的io写,针对这两个问题,第一个可以采用lambda+判定开关降低性能开销,第二个可以采用基于epoll原型的nio方式,第二个问题展开讲在这里会有跑题的嫌疑,所以暂且不表。关于第一个问题,具体处理:

·重写logger类的debug方法:

    public void debug(Supplier<String> message) {

        if(isDebugEnaled()){

            debug(message.get());

        }

    }

·日志判定采用lambda参数:

    Logger log = new Logger();

    log.debug(() -> "xxxx");


这里对于Supplier<String> message简单看一下,supplier意为供应商,位于java.util.function.Supplier接口,提供一个get方法获取泛型参数指定类型的对象元素,接口定义为:

    @FunctionalInterface

    public interface Supplier<T> {

        /**

         * Gets a result.

         *

         * @return a result

         */

        T get();

    }


函数式中对于基本类型、装箱类型的拆装箱处理



    在java中有时我们想要一个包含整数型值的List<int>,实际返回得到的却是List<Integer>,原因是java的泛型类型擦除,这个问题进而导致的就是带来对于基本类型进行拆封箱的内存消耗,基本类型和封装类型在内存中的占用字节不同,导致额外开销随着数值运算的复杂度正向增加。


    为了减小这类的性能开销,java8中stream对于整型、长整型、双浮点数进行了特殊处理,stream方法中命名带有to或以类型名开头的方法即是,因为经过了改善和优化,所以要尽可能多的使用这类函数,此外它还有很多额外的方法,可以避免我们重复造轮子实现一些通用且容易处bug的方法。


重载解析



    java通过不同方法签名实现重载,这对于stream推断类型时会带来问题,导致推断出很多种类型,所以javac会挑出最具体的类型,对此有一个默认的规则:

·只有一个可能的目标类型,由相应函数接口的参数类型推到;

·有多个可能的目标类型,由最具体的类型推导得出;

·有多个可能的目标类型且最具体的类型不明确,需要人为指定类型;


@FunctionalInterface



    为提高stream对象可操作性而引入的各类接口,都需要lambda表达式恶意实现它们,这类接口存在的意义是将代码块作为数据打包起来,这正是通过@FunctionalInterface做到的,@FunctionalInterface会强制javac检查一个接口是否符合函数接口标准,如果这个注释加到枚举类、类或另一个注释或接口包含不止一个抽象方法,在javac层面就会报错,使用它在重构代码时能很快发现问题。


结语



    最近这段时间因为家庭和公司琐事,导致更新变慢,承蒙各位错爱,惶恐惶恐。后面地更新里,雷记打算尝试加一些vue的前端内容,进而最终过渡到小程序和app制作上,目前是这么打算。如果各位看官有更好的想法,欢迎私信雷记交流,那么今天的更新就是这样,愿诸位,酒色财气君莫占,招财进宝,日进斗金~