Java Function & Supplier 的实际例子对比感受抽象和懒加载

Posted master-dragon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java Function & Supplier 的实际例子对比感受抽象和懒加载相关的知识,希望对你有一定的参考价值。

目录

Supplier实际例子

以人使用交通工具出行为例(交通工具称为人的属性,人外出时要使用到交通工具)

非Supplier代码

如下:很自然的代码如下,没有任何问题


interface Vehicle 
    void drive();


class Car implements Vehicle 

    public Car() 
        System.out.println("new Car()");
    

    @Override
    public void drive() 
        System.out.println("car...");
    


class SubWay implements Vehicle 

    public SubWay() 
        System.out.println("new SubWay()");
    

    @Override
    public void drive() 
        System.out.println("subway...");
    


class People 
    Vehicle vehicle;
    String name;

    public People(Vehicle vehicle, String name) 
        this.vehicle = vehicle;
        this.name = name;
    

    void goToDestination() 
        this.vehicle.drive();
        System.out.println(name + ",arrive destination");
    

    void sleep() 
        System.out.println(name + ",just sleep");
    



public class SupplierTest 

    public static void main(String[] args) 
        People p1 = new People(new Car(), "Xiaohang");
        p1.goToDestination();

        System.out.println("------------");

        People p2 = new People(new SubWay(), "XiaoWang");
        p2.sleep();
    

输出如下

new Car()
car...
Xiaohang,arrive destination
------------
new SubWay()
XiaoWang,just sleep

可以看到,构造人对象的时候,必须得先构造交通工具,然后可以使用

如果使用Supplier


import java.util.function.Supplier;

interface Vehicle 
    void drive();


class Car implements Vehicle 

    public Car() 
        System.out.println("new Car()");
    

    @Override
    public void drive() 
        System.out.println("car...");
    


class SubWay implements Vehicle 

    public SubWay() 
        System.out.println("new SubWay()");
    

    @Override
    public void drive() 
        System.out.println("subway...");
    


class People 
    Supplier<Vehicle> vehicleSupplier;
    String name;

    public People(Supplier<Vehicle> vehicleSupplier, String name) 
        this.vehicleSupplier = vehicleSupplier;
        this.name = name;
    

    void goToDestination() 
        this.vehicleSupplier.get().drive();
        System.out.println(name + ",arrive destination");
    

    void sleep() 
        System.out.println(name + ",just sleep");
    



public class SupplierTest 

    public static void main(String[] args) 
        Supplier<Vehicle> carSupplier = new Supplier<Vehicle>() 
            @Override
            public Vehicle get() 
                return new Car();
            
        ;

        Supplier<Vehicle> subWaySupplier = new Supplier<Vehicle>() 
            @Override
            public Vehicle get() 
                return new SubWay();
            
        ;

        People p1 = new People(carSupplier, "XiaozZhang");
        p1.goToDestination();

        System.out.println("------------");

        People p2 = new People(subWaySupplier, "XiaoWang");
        p2.sleep();
    

输出如下:

new Car()
car...
XiaozZhang,arrive destination
------------
XiaoWang,just sleep

可以看到,小王在家睡觉都没出去,压根用不到交通工具,不用new对象(理解supplier单词:供应者,补充者,补给人;交通工具并不是人必须要有实物的对象,因为可以不外出,交通工具是个补充工具而已)

Function函数式接口

非 Function 例子

如下代码:Facade类提供了check方法,Listener需要使用其方法;没办法,只能使用setFacade主动设置一个还没有初始化的Facade,虽然Listener只需要使用其check方法,不过facade因为必须要先添加Listener才能完成初始化操作;所以本例有两个具体listener,都要设置facade对象进去,只是使用facade不同的方法而已


import java.util.ArrayList;
import java.util.List;

interface Listener 
    void init();

    Boolean check(int a, int b, int c);


class Listener1 implements Listener 
    private String name;
    private Facade facade;

    Listener1(String name) 
        this.name = name;
    

    @Override
    public Boolean check(int a, int b, int c) 
        int ans = facade.add(a, b);
        return ans == c;
    

    @Override
    public void init() 
        System.out.println("register name" + name);
    

    public Facade getFacade() 
        return facade;
    

    public void setFacade(Facade facade) 
        this.facade = facade;
    


class Listener2 implements Listener 
    private String name;
    private Facade facade;

    Listener2(String name) 
        this.name = name;
    

    @Override
    public Boolean check(int a, int b, int c) 
        int ans = facade.sub(a, b);
        return ans == c;
    

    @Override
    public void init() 
        System.out.println("register name" + name);
    

    public Facade getFacade() 
        return facade;
    

    public void setFacade(Facade facade) 
        this.facade = facade;
    


class Facade 

    List<Listener> listeners;

    public Facade() 
        this.listeners = new ArrayList<>();
    

    Integer add(Integer a, Integer b) 
        return a + b;
    

    Integer sub(Integer a, Integer b) 
        return a - b;
    

    public Facade(List<Listener> listeners) 
        this.listeners = listeners;
    

    public void addListener(Listener listener) 
        listeners.add(listener);
    

    void init() 
        for (Listener listener : listeners) 
            listener.init();
        
    


public class Test2 

    public static void main(String[] args) throws Exception 
        Facade facade = new Facade();
        Listener1 listener1 = new Listener1("l1");
        listener1.setFacade(facade);

        Listener2 listener2 = new Listener2("l2");
        listener2.setFacade(facade);

        facade.addListener(listener1);
        facade.addListener(listener2);
        facade.init();

        System.out.println(listener1.check(1, 2, 3));
        System.out.println(listener1.check(1, 1, 3));

        System.out.println(listener2.check(3, 2, 1));
        System.out.println(listener2.check(3, 1, 1));
    


Function函数式编程例子

考虑Function, 如下,既然Listener只需要使用Facade的check能力,那么完全可以抽象出来,解耦开,Listener用到的时候自然会去执行对应check能力


import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;


interface Listener 
    void init();

    Boolean check(int a, int b, int c);


class ListenerImpl implements Listener
    private String name;
    private BiFunction<Integer, Integer, Integer> function;

    ListenerImpl(BiFunction<Integer, Integer,Integer> function, String name)
        this.function = function;
        this.name = name;
    

    @Override
    public Boolean check(int a, int b, int c)
        int ans = function.apply(a, b);
        return ans == c;
    

    @Override
    public void init()
        System.out.println("register name" + name);
    


class Facade 

    List<Listener> listeners;

    public Facade() 
        this.listeners = new ArrayList<>();
    

    Integer add(Integer a, Integer b) 
        return a + b;
    

    Integer sub(Integer a, Integer b)
        return a - b;
    

    public Facade(List<Listener> listeners) 
        this.listeners = listeners;
    

    public void addListener(Listener listener) 
        listeners.add(listener);
    

    void init()
        for(Listener listener: listeners)
            listener.init();
        
    

public class Test 

    public static void main(String[] args) throws Exception 
        Facade facade = new Facade();
        Listener listener1 = new ListenerImpl(facade::add, "l1");
        Listener listener2 = new ListenerImpl(facade::sub, "l2");
        facade.addListener(listener1);
        facade.addListener(listener2);
        facade.init();

        System.out.println(listener1.check(1, 2, 3));
        System.out.println(listener1.check(1, 1, 3));

        System.out.println(listener2.check(3, 2, 1));
        System.out.println(listener2.check(3, 1, 1));
    


并且这次不用写两个Listener实现类了,因为构造的时候可以直接传递lambda函数表达式了

附:BiFunction 函数式接口

@FunctionalInterface
public interface BiFunction<T, U, R> 

    /**
     * Applies this function to the given arguments.
     *
     * @param t the first function argument
     * @param u the second function argument
     * @return the function result
     */
    R apply(T t, U u);

    /**
     * Returns a composed function that first applies this function to
     * its input, and then applies the @code after function to the result.
     * If evaluation of either function throws an exception, it is relayed to
     * the caller of the composed function.
     *
     * @param <V> the type of output of the @code after function, and of the
     *           composed function
     * @param after the function to apply after this function is applied
     * @return a composed function that first applies this function and then
     * applies the @code after function
     * @throws NullPointerException if after is null
     */
    default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) 
        Objects.requireNonNull(after);
        return (T t, U u) -> after.apply(apply(t, u));
    

以上是关于Java Function & Supplier 的实际例子对比感受抽象和懒加载的主要内容,如果未能解决你的问题,请参考以下文章

Java Function & Supplier的实际例子对比感受抽象和懒加载

Java Function & Supplier的实际例子对比感受抽象和懒加载

Java Function & Supplier的实际例子对比感受抽象和懒加载

Java Function & Supplier的实际例子对比感受抽象和懒加载

JavaScript 没有函数重载&amp;Arguments对象

[Python]reduce function & lambda function & factorial