1  有用部分

2    常用函数列表

demo1 方法和总结

demo2 方法

demo3优点:  函数式编程的优点是什么?为什么要使用函数式编程?

 

 

2  常用函数列表

接口        |参数     |返回类型    |描述
Predicate<T>    T       |boolean     |用于判别一个对象。比如求一个人是否为男性

Consumer<T>,   T      void       用于接收一个对象进行处理但没有返回,比如接收一个人并打印他的名字

Function<T,R>   T      |R       |转换一个对象为不同类型的对象

Supplier<T>    |None     T        |提供一个对象

UnaryOperator<T> T      T        接收对象并返回同类型的对象

BinaryOperator<T>|(T,T)   T        接收两个同类型的对象,并返回一个原类型对象

 

 

3  demo1 关于Funtion<T,R>的应用(讲师没有给demo,自己写的,有不对的地方请指教)

需求:
把FWM狙击枪(其实是AWM)的属性赋给玩具枪

 

Gun接口:

package com.ddwei.chapter1.entity;

public interface Gun {
    void shoot();
}

 

 

FWM实现类:

package com.ddwei.chapter1.entity;

public class FWMGun implements Gun{
    private String color;           //枪体颜色
    private String bulletNumber;    //弹夹数


    @Override
    public void shoot() {

    }

    /**
     * 有参构造函数
     * @param color
     * @param bulletNumber
     */
    public FWMGun(String color, String bulletNumber) {
        this.color = color;
        this.bulletNumber = bulletNumber;
    }

    @Override
    public String toString() {
        return "FWM狙击枪{" +
                "颜色为'" + color + '\'' +
                ", 子弹数量为'" + bulletNumber + '\'' +
                '}';
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getBulletNumber() {
        return bulletNumber;
    }

    public void setBulletNumber(String bulletNumber) {
        this.bulletNumber = bulletNumber;
    }
}

 

 

ToyGun实现类:

package com.ddwei.chapter1.entity;

/**
 * 玩具枪
 */
public class ToyGun implements Gun{
    private String color;           //枪体颜色
    private String bulletNumber;    //弹夹数


    @Override
    public void shoot() {

    }

    @Override
    public String toString() {
        return "玩具枪{" +
                "颜色为'" + color + '\'' +
                ", 子弹数量为'" + bulletNumber + '\'' +
                '}';
    }


    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getBulletNumber() {
        return bulletNumber;
    }

    public void setBulletNumber(String bulletNumber) {
        this.bulletNumber = bulletNumber;
    }

}

 

 

服务类:

package com.ddwei.chapter1.entity;

import java.util.function.Function;

public class GunService implements Function {


  /**  重写了apply方法
   */
    @Override
    public ToyGun apply(Object o) {
        ToyGun toyGun = new ToyGun();
        FWMGun fwmGun = (FWMGun) o;
        toyGun.setColor(fwmGun.getColor());
        toyGun.setBulletNumber(fwmGun.getBulletNumber());
        return toyGun;
    }
}

 

 

测试类:

package com.ddwei.chapter1;

import com.ddwei.chapter1.entity.FWMGun;
import com.ddwei.chapter1.entity.Gun;
import com.ddwei.chapter1.entity.GunService;
import com.ddwei.chapter1.entity.ToyGun;
import org.junit.Test;

public class TestGun {

    @Test
    public void testChangeGun(){
        //把fwm 狙击枪 的属性 赋给 玩具枪

        //打印出玩具枪属性,方便和下方进行对比
        Gun fwmGun = new FWMGun("金黄色","30");
        ToyGun toyGun = new ToyGun();
        toyGun.setColor("黑色");
        toyGun.setBulletNumber("12");

        System.out.println(fwmGun);
        System.out.println(toyGun);

        GunService gunService = new GunService();
        toyGun = gunService.apply(fwmGun);
        System.out.println(toyGun);


    }

}

 

 

打印日志:

FWM狙击枪{颜色为'金黄色', 子弹数量为'30'}
玩具枪{颜色为'黑色', 子弹数量为'12'}
玩具枪{颜色为'金黄色', 子弹数量为'30'}

Process finished with exit code 0

 

 

自己理解:根据不同的业务场景(比如,A类向B类赋很多值,A类中C条记录 赋值 给D条记录),调用相应的接口,实现了规范化。

以后找类的时候,直接根据相应接口 的Ctrl T就可以找到。

 

 

 

4  demo2 关于Function的应用(网上摘抄改造的关于 函数式编程调用的应用)

接口:

package com.ddwei.chapter1.entity;
public interface Clazz {
    public void m();
    public void n();
}

 

 

实现类1:

package com.ddwei.chapter1.entity;
public class Clazz1 implements Clazz{
    public Clazz1() {
        System.out.println("Clazz1");
    }
    @Override
    public void m(){
        System.out.println("m1");
    }

    @Override
    public void n() {
        System.out.println("n1");
    }
}

 

 

实现类2:

package com.ddwei.chapter1.entity;
public class Clazz2 implements Clazz{
    public Clazz2() {
        System.out.println("Clazz2");
    }
    @Override
    public void m(){
        System.out.println("m2");
    }

    @Override
    public void n() {
        System.out.println("n2");
    }
}

 

 

测试类:

package com.ddwei.chapter1;
import com.ddwei.chapter1.entity.Clazz;
import com.ddwei.chapter1.entity.Clazz1;
import com.ddwei.chapter1.entity.Clazz2;

import java.util.function.Function;
public class Main {
    public static void main(String[] args){
        System.out.println("main");
        Main main = new Main();
        main.F(new Clazz1());
        System.out.println("==========");
        main.F(new Clazz2());
    }

    public void F(Clazz clazz){
        //声明函数f
        Function f = Function.identity();

        //将函数应用到类中(可能是不同的类)
        clazz = (Clazz) f.apply(clazz);
        clazz.n();
    }
}

 

 

打印日志:

main
Clazz1
n1
==========
Clazz2
n2

Process finished with exit code 0

 

 

 

问题:

4.1 优点:参照demo3

4.2 这个函数式编程不满足 接口中必须只有一个方法的定义啊,详细参考2-9中第5条

 

 

 

 

 

5  demo3 关于为什么要用函数式接口

需求:

如果我是顺丰,我来负责淘宝,京东和拼多多的商品配送服务。我需要设计一个根据订单信息计算邮费的接口,三个电商网站系统调用我这个接口给用户计算邮费。应该怎么设计?

需要考虑如下几个问题点:

第一:三个电商有自己不同的免邮费政策,比如:淘宝大于100件包邮,京东订单满99包邮,拼多多...如何才能在邮费计算的接口中根据不同电商平台,分别调用他们的免邮政策呢?

第二:顺丰有自己的邮费计算规则,比如:基础运费10元,超重增加10元,超体积增加10元...这部分逻辑应该是通用的,只要不免邮费,就要调用这段逻辑计算邮费。如何将个性化的逻辑和通用的逻辑整合到一个接口中呢?

第三:如何设计才能最容易扩展,为以后对接其他平台预留灵活性?

 

 

常规设计:

 

函数式编程设计:

 

优点:

函数式接口就是将业务逻辑参数化。

 

第一:邮费计算接口中只包含相对固定,通用的业务逻辑,将定制化强的业务逻辑作为一个参数,让调用方自己定义。

第二:以后扩展第四家也非常简单,因为接口是通用的。

第三:以后如果扩展接口的实现逻辑,比如:当判断免邮后,记录一条免邮信息。或者给用户发送免邮短信等。只需要稍作修改就行。

类似与规则引擎,只需要给我订单信息规则,我会自动计算。例如 金额小于1000的规则,  规则中金额入参1000,订单中自带金额 ,让两个金额比较。

 

posted on 2020-04-05 10:16  菜鸟乙  阅读(237)  评论(0编辑  收藏  举报