栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java8新特性--函数式接口

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java8新特性--函数式接口

工作这么久了,也是最近半年才注意到java.util.function。以前都完全没有使用过这个包,因此当第一次看见这个的时候就比较蒙圈。原谅我的寡闻。

我也是网上百度了一下。

https://blog.csdn.net/weixin_43415201/article/details/109957738https://blog.csdn.net/weixin_43415201/article/details/109957738网上讲得其实也算比较透彻。

接口

总结来说有四个接口。

Function:通俗理解为具体执行方法的执行体

表示接受一个参数并生成结果的函数。并且核心的方法是apply方法,表示执行。

Consumer:消费者。通俗理解为拿到数据后需要执行的操作。

 表示接受单个输入参数但不返回结果的操作。与大多数其他功能接口不同,消费者需要通过另一侧进行操作。

Supplier:供给者。提供数据的一方。

Predicate:用于测试一个方法。返回true或false。

 通过这四个接口可以发现,其思想与消息中间件有类似之处。都有消息提供者和消息消费者模式,但是不同的是,这里并不算是异步的,Supplier只是提供了一个存储值的功能。而consumer则是提供了一个执行定义方法的功能。且consumer是void方法。分开使用也可。其实主要还是用于抽象统一。

应用

那有没有什么比较好的应用呢?

有。那就是模板模式。

假设纯牛奶和特仑苏的生产工序基本一样,但是某个来源和关键步骤是不同的。那么应该是什么样的代码呢?

首先要定义一个模板类。

package com.xq.traditonal.impl;


public abstract class AbstractProcess {
    // 牛奶工序流程
    public String execute(){
        String f = commonHandle();
        String sec = specialHandle(f);
        return assemble(sec);
    }
    // 组装处理
    private String assemble(String sec) {
        return sec + " 组装完成n";
    }
    // 公共处理
    private String commonHandle() {
        return "通用处理一。n" ;
    }
    // 特殊处理
    abstract String specialHandle(String source);
}

然后继承模板类定义各自的具体逻辑。

package com.xq.traditonal.impl;


public class PureMilk extends AbstractProcess{
    private String name;

    public PureMilk() {
        name = "纯牛奶";
    }
    @Override
    String specialHandle(String source) {
        return source + name + "杀菌+消毒+防腐剂。n";
    }
}
package com.xq.traditonal.impl;


public class Terentsu extends AbstractProcess{
    private String name;

    public Terentsu() {
        name = "特仑苏";
    }
    @Override
    String specialHandle(String source) {
        return source + name + "杀菌+消毒n";
    }
}

最后在测试一下:

package com.xq.traditonal;

import com.xq.traditonal.impl.PureMilk;
import com.xq.traditonal.impl.Terentsu;

public class TraditionalTest {
    public static void main(String[] args) {
        PureMilk pureMilk = new PureMilk();
        System.out.println(pureMilk.execute());

        Terentsu terentsu = new Terentsu();
        System.out.println(terentsu.execute());
    }
}

结果如下:

现在只有 特仑苏和纯牛奶。市面上的牛奶品种可是要非常多的,要是让你实现十几种,岂不是要多加10多个文件!

现在我们改成使用suppiler和consumer的方式实现。

这种方式要简洁很多!

我们需要将抽象类改造一下。

package com.xq.func.impl;

import java.util.function.Consumer;
import java.util.function.Supplier;


public class FuncProcess {
    // 牛奶工序流程
    private StringBuilder execute(Supplier supplier, Consumer consumer){
        StringBuilder f = commonHandle();
        StringBuilder stringBuilder = f.append(supplier.get());
        consumer.accept(stringBuilder);
        return assemble(stringBuilder);
    }
    // 组装处理
    private StringBuilder assemble(StringBuilder sec) {
        return sec .append(" 组装完成n");
    }
    // 公共处理
    private StringBuilder commonHandle() {
        return new StringBuilder("通用处理一。n") ;
    }

    // 纯牛奶
    public String pure() {
        return execute(() ->new StringBuilder("纯牛奶"), c -> c.append("杀菌+消毒+防腐剂。n")).toString();
    }

    // 特仑苏
    public String terensu() {
        return execute(() ->new StringBuilder("特仑苏"), c -> c.append("杀菌+消毒n")).toString();
    }
}

可以看见我们将execute的模板定义好后直接使用匿名函数的形式填充了模板所需要的方法。

Supplier充当了牛奶来源(纯牛奶or特仑苏)。
Consumer充当了特殊处理。

如果有多个特殊处理怎么办?多加几个consumer作为入参就行了。Supplier同理。

写如下测试用例:

package com.xq.func;

import com.xq.func.impl.FuncProcess;

public class FuncTest {
    public static void main(String[] args) {
        FuncProcess funcProcess = new FuncProcess();
        System.out.println(funcProcess.pure());
        System.out.println(funcProcess.terensu());
    }
}

结果:

当然,这个明显有弊端。 最大的弊端就是consumer没有返回值,所以在正常的模板模式中这些都不限制,但是在第二种需要传引用方便修改,显得有点不雅观,别扭,最好还是用于comsumer处理不需要返回的情况,比较合适。

结论

考虑的情况。

实现种类很多且都相对简单。采用suppllier,consumer方式。

想要灵活一点且种类并不多的情况。采用传统的模板模式更容易理解。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/999215.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号