资讯专栏INFORMATION COLUMN

Java8-3-深入理解函数式编程模型

longshengwang / 297人阅读

摘要:接下来看下如果使用提供的接口会有哪些改进首先看下接口定义省略该函数式接口唯一的抽象方法接收一个参数,有返回值。是不是有点体验到函数式编程的灵活之处。

上一篇文章中,我们总体介绍了创建函数式接口实例的几种方式以及Java8中接口新增的默认方法特性,接下来我们来看下Java8中已经为我们提供的几种典型的函数式接口
先看一个示例

public class FunctionTest {
    public static void main(String[] args) {
        FunctionTest functionTest = new FunctionTest();
        int i2 = functionTest.add2(2);
        int i3 = functionTest.add3(2);
        int i4 = functionTest.add4(2);
    }

    //逻辑提前定义好
    public int add2(int i){
        return i + 2;
    }

    //逻辑提前定义好
    public int add3(int i){
        return i + 3;
    }

    //逻辑提前定义好
    public int add4(int i){
        return i + 4;
    }
}

FunctionTest中定义了三个方法,分别把参数加2,加3,加4然后分别把结果返回,那如果以后还要取到参数的平方或者各种其他的运算,就还需要定义更多的处理方法。接下来看下如果使用Java8提供的Function接口会有哪些改进
首先看下Function接口定义

@FunctionalInterface
public interface Function {

    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);
    .
    .省略
    .
}

该函数式接口唯一的抽象方法apply接收一个参数,有返回值。看下使用方式

public class FunctionTest {
    public static void main(String[] args) {
        FunctionTest functionTest = new FunctionTest();

        int result2 = functionTest.compute(5, num -> num + 2);
        int result3 = functionTest.compute(5, num -> num + 2);
        int result4 = functionTest.compute(5, num -> num + 2);
        int results = functionTest.compute(5, num -> num * num);

    }

    //调用时传入逻辑
    public int compute(int i, Function function){
        Integer result = function.apply(i);
        return result;
    }
}

我们在FunctionTest中定义了compute方法,方法的第一个参数是要运算的数据,第二个参数是函数式接口Function的实例,当执行compute方法时,会将第一个参数交给第二个参数Function中的apply方法处理,然后返回结果。
这样我们可以将方法定义的更抽象,代码重用性也就越高,每次将要计算的数据和计算逻辑一起作为参数传递给compute方法就可以。是不是有点体验到函数式编程的灵活之处。
注:因为表达式只有一行语句 num -> num + 2 可以省略了return 关键字 如果为了更加直观可以写成 num -> return num + 2

Supplier接口,默认抽象方法get不接收参数,有返回值

@FunctionalInterface
public interface Supplier {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

类似工厂模式

public class SupplierTest {
    public static void main(String[] args) {
        Supplier supplier = String::new;
        String s = supplier.get();
    }
}

这里使用构造方法引用的方式创建Supplier实例,通过get直接返回String对象

Predicate接口

@FunctionalInterface
public interface Predicate {

    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);
    .
    .省略
    .
}

接收一个参数,返回布尔类型,使用方式

public class PredicateTest {
    public static void main(String[] args) {
        Predicate predicate = s -> s.length() > 5;
        System.out.println(predicate.test("hello"));
    }
}

定义了一个接收一个参数返回布尔值的lambda表达式,赋值给predicate,就可以直接对传入参数进行校验

再看一个Predicate例子

public class PredicateTest {
    public static void main(String[] args) {
        List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        PredicateTest predicateTest = new PredicateTest();
        List result = predicateTest.conditionFilter(list, integer -> integer > 5);
        result.forEach(System.out::println);
    }

    public List conditionFilter(List list, Predicate predicate){
        return list.stream().filter(predicate).collect(Collectors.toList());
    }
}

这段程序的逻辑是找到集合里大于5的数据,打印到控制台。我们具体分析一下conditionFilter方法,第一个参数是待遍历的集合,第二个参数是Predicate类型的实例,还记得Predicate接口中的抽象方法定义吗,接收一个参数返回布尔类型。list.stream()是创建了一个针对此集合的Stream对象(先简单认识一下),然后调用Stream的filter方法对结果进行过滤,过滤的条件就是Predicate接口的实现,最后collect(Collectors.toList());是将过滤后的结果收集起来放置到一个新的集合中并返回。
其中涉及到Srteam api的知识点我们会在后续章节中详细介绍,现在只关心Predicate的使用就可以。

接下来调用conditionFilter方法

List result = predicateTest.conditionFilter(list, integer -> integer > 5);

list是待遍历的集合
integer -> integer > 5 lambda表达式是对Predicate接口的具体实现

result.forEach(System.out::println);

最后,方法引用实例化一个Consumer对象,把结果输出到控制台。

可以看出,lambda表达式和stream api结合起来使用让代码更简洁更加语义化,即使之前没接触过stream api也能大概看出conditionFilter方法的功能。

小结:本篇继续介绍Java8函数式编程模型,介绍了几个内置的函数式接口使用方式,并在最后一个示例引出stream api知识点,后续会对stream api进行详细的介绍,如果觉得本篇文章对你有所帮助帮忙赞一下。

下一篇

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70677.html

相关文章

  • 深入React知识点整理(一)

    摘要:以我自己的理解,函数式编程就是以函数为中心,将大段过程拆成一个个函数,组合嵌套使用。越来越多的迹象表明,函数式编程已经不再是学术界的最爱,开始大踏步地在业界投入实用。也许继面向对象编程之后,函数式编程会成为下一个编程的主流范式。 使用React也满一年了,从刚刚会使用到逐渐探究其底层实现,以便学习几招奇技淫巧从而在自己的代码中使用,写出高效的代码。下面整理一些知识点,算是React看书...

    Gilbertat 评论0 收藏0
  • JS程序

    摘要:设计模式是以面向对象编程为基础的,的面向对象编程和传统的的面向对象编程有些差别,这让我一开始接触的时候感到十分痛苦,但是这只能靠自己慢慢积累慢慢思考。想继续了解设计模式必须要先搞懂面向对象编程,否则只会让你自己更痛苦。 JavaScript 中的构造函数 学习总结。知识只有分享才有存在的意义。 是时候替换你的 for 循环大法了~ 《小分享》JavaScript中数组的那些迭代方法~ ...

    melody_lql 评论0 收藏0
  • JavaScript深入浅出

    摘要:理解的函数基础要搞好深入浅出原型使用原型模型,虽然这经常被当作缺点提及,但是只要善于运用,其实基于原型的继承模型比传统的类继承还要强大。中文指南基本操作指南二继续熟悉的几对方法,包括,,。商业转载请联系作者获得授权,非商业转载请注明出处。 怎样使用 this 因为本人属于伪前端,因此文中只看懂了 8 成左右,希望能够给大家带来帮助....(据说是阿里的前端妹子写的) this 的值到底...

    blair 评论0 收藏0
  • 7个 Javascript 面试题及回答策略

    摘要:使用异步编程,有一个事件循环。它作为面向对象编程的替代方案,其中应用状态通常与对象中的方法搭配并共享。在用面向对象编程时遇到不同的组件竞争相同的资源的时候,更是如此。 翻译:疯狂的技术宅原文:https://www.indeed.com/hire/i... 本文首发微信公众号:jingchengyideng欢迎关注,每天都给你推送新鲜的前端技术文章 不管你是面试官还是求职者,里面...

    李义 评论0 收藏0
  • 双十二大前端工程师读书清单

    摘要:本文最早为双十一而作,原标题双大前端工程师读书清单,以付费的形式发布在上。发布完本次预告后,捕捉到了一个友善的吐槽读书清单也要收费。这本书便从的异步编程讲起,帮助我们设计快速响应的网络应用,而非简单的页面。 本文最早为双十一而作,原标题双 11 大前端工程师读书清单,以付费的形式发布在 GitChat 上。发布之后在读者圈群聊中和读者进行了深入的交流,现免费分享到这里,不足之处欢迎指教...

    happen 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<