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));
    }
}

猜你喜欢

转载自blog.csdn.net/qq_26437925/article/details/121593411