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 ?
答案 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);
}
}