java 8 java.util.function.Function downcast

时间:2017-07-12 08:16:39

标签: java-8

The below java function is assignable (f(Order) to f(Object))

    Function<Order, Order> orderProcessor = (Order order) -> {
        System.out.println("Processing Order:" 
        return order;
    };

Function f = orderProcessor;

The question is how do i cast this function back to Function < Order,Order> ?

or better I would like to cast this function back to Function < SomeInterface,SomeInterface>

I am storing these functions in a List< Function> but ideally i would like to store them in a List < SomeInterface,SomeInterface>. Is it possible ?

1 个答案:

答案 0 :(得分:0)

您可以使用2个通用参数List定义Function? extends SomeInterface次。然后根本不需要施法,例如:

List<Function<? extends SomeInterface, ? extends SomeInterface>> functions =
                                                                 new ArrayList<>();

Function<Order, Order> orderProcessor = (Order order) -> {
    System.out.println("Processing Order:" + order);
    return order;
};

functions.add(orderProcessor);

IF 结果类型与参数类型相同,您也可以改为使用UnaryOperator,例如:

List<UnaryOperator<? extends SomeInterface>> functions = new ArrayList<>();

UnaryOperator<Order> orderProcessor = (Order order) -> {
    System.out.println("Processing Order:" + order);
    return order;
};

functions.add(orderProcessor);

然后您根本无法接受任何SomeInterface,因为Function<? extends SomeInterface>不仅可以为Order类采用任何其他子类型。

IF 您希望Function可以接受其所有子类型,您必须将其声明为写入模式? super SomeInterface,然后您必须更改UnaryOperator<Order> }定义,例如:

List<UnaryOperator<? super SomeInterface>> functions = new ArrayList<>();

UnaryOperator<SomeInterface> orderProcessor = (SomeInterface item) -> {
    if(item instanceof Order){
       System.out.println("Processing Order:" + order);
    }
    return item;
};

functions.add(orderProcessor);

这是Map中的Processors解决方案,然后您不需要instanceof正文中的任何演员或UnaryOperator声明,例如:

Processors processors = new Processors();

UnaryOperator<Order> orderProcessor = (order) -> {
    // no need instanceof & casting expression here
    System.out.println("Processing Order:" + order);
    return order;
};

processors.add(Order.class, orderProcessor);


processors.listing(Order.class).forEach(it -> it.apply(new Order()));
class Processors {
    private final Map<Class<?>, List<UnaryOperator<?>>> registry = new HashMap<>();

    public <T extends SomeInterface> void add(Class<T> type,
                                              UnaryOperator<T> processor) {
        registry.computeIfAbsent(type, aClass -> new ArrayList<>()).add(processor);
    }

    @SuppressWarnings("unchecked")
    public <T extends SomeInterface> 
    Stream<UnaryOperator<T>> listing(Class<T> type){
        return (Stream<UnaryOperator<T>>) lookup(type).stream();
    }

    private List<?> lookup(Class<?> type) {
        if (!SomeInterface.class.isAssignableFrom(type)) 
            return Collections.emptyList();

        if (!registry.containsKey(type)) 
            return registry.get(type.getSuperclass());

        return registry.get(type);
    }
}