Java 8 java 8 java.util.function.function downcast

Java 8 java 8 java.util.function.function downcast,java-8,Java 8,下面的java函数是可赋值的(f(顺序)到f(对象)) 函数orderProcessor=(订单)->{ System.out.println(“处理订单:” 退货单; }; 函数f=orderProcessor; 问题是如何将此函数转换回函数 或者更好,我想把这个函数转换回函数 我将这些函数存储在列表中,但理想情况下,我希望将它们存储在列表中。 有可能吗?您可以定义一个列表函数s,其中包含两个通用参数?扩展一些接口。然后根本不需要强制转换,例如: List<Function<?

下面的java函数是可赋值的(f(顺序)到f(对象))

函数orderProcessor=(订单)->{
System.out.println(“处理订单:”
退货单;
};
函数f=orderProcessor;

问题是如何将此函数转换回函数

或者更好,我想把这个函数转换回函数

我将这些函数存储在列表中,但理想情况下,我希望将它们存储在列表中。
有可能吗?

您可以定义一个
列表
函数s,其中包含两个通用参数
?扩展一些接口
。然后根本不需要强制转换,例如:

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);
List<UnaryOperator<? extends SomeInterface>> functions = new ArrayList<>();

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

functions.add(orderProcessor);
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);
这里有一个解决方案,将
映射
包装在
处理器
中,这样您就不需要在
UnaryOperator
主体中使用任何强制转换或
instanceof
语句,例如:

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()));
Processors=新处理器();
UnaryOperator orderProcessor=(订单)->{
//此处不需要instanceof&casting表达式
System.out.println(“处理订单:+订单”);
退货单;
};
processors.add(Order.class,orderProcessor);
processors.listing(Order.class).forEach(it->it.apply(neworder());

类处理器{
私有最终映射>>注册表=新HashMap();
公共void add(类类型,
单核处理器(操作员处理器){
registry.computeifassent(type,aClass->newarraylist()).add(processor);
}
@抑制警告(“未选中”)
公开的
流列表(类类型){
返回(流)查找(类型).Stream();
}
私有列表查找(类类型){
如果(!SomeInterface.class.isAssignableFrom(类型))
返回集合。emptyList();
如果(!registry.containsKey(类型))
返回registry.get(type.getSuperclass());
返回registry.get(类型);
}
}

uhm…不需要强制转换-此函数已经有您提到的签名。您是否因为lambda符号而感到困惑?当您将,
函数
分配给
函数
时,您将其分配给原始类型
函数
,而不是
函数
或其他任何类型。您正在删除类型信息,并且没有,再次强调:不需要强制转换,将
函数
强制转换为
函数
…甚至没有任何意义,
列表
?!一个
函数
不能强制转换为
函数
,仅仅因为它不能接受
SomeInterface
的实现t不是
Order
参数。如果需要,您可以将其强制转换为
Function
(假设
Order
实现了该接口)。让
?为
函数
的输入参数扩展SomeInterface
是没有意义的。这会使函数不可用。很漂亮。但由于某种原因,我现在尝试调用f.apply(SomeInterface)时遇到编译器错误@user2894020这是因为
?扩展了一些接口
不仅可以接受
订单
的任何子类。因此这些函数无法确保您可以安全地接受
订单。例如:另一个函数
二进制运算符
只支持
BackedOrder
@Holger,还有什么选择?我只是在尝试g保存(在列表中)并基于接口“多态”地使用/调用函数。这可能吗?@user2894020:您必须改进您的问题,告诉更多您实际想要做的事情。如果可能,使用更多实际代码。
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);
    }
}