3 回答
TA贡献1840条经验 获得超5个赞
如果我了解您要查找的内容,我会重载end()并摆脱最后一个函数组合:
public Function<InType, CurrentType> end() {
return this.getter;
}
进一步思考,我认为Context可以消除类的第三个类型参数,因为仅在方法级别需要中间类型。检查这个:
class OtherContext<I, O> {
private final Function<I, O> getter;
public OtherContext(Function<I, O> getter) {
this.getter = getter;
}
public <T> OtherContext<I, T> pipe(Function<O, T> mapper) {
return new OtherContext<I, T>(getter.andThen(mapper));
}
public <T> Function<I, T> end(Function<O, T> mapper) {
return getter.andThen(mapper);
}
public Function<I, O> end() {
return getter;
}
}
TA贡献1864条经验 获得超6个赞
您不能在 Java 中定义具有相同名称和不同返回类型的方法。您的方法可能会返回类似的东西Wrapped<T>
,而您想要返回T
。一般来说,我可能会建议为*andEnd(...)
您的每种方法设置类似的东西。管道也是如此pipeAndEnd(...)
,然后以终端操作结束。这可能会变得乏味,因此如果您有很多方法,您可能想研究一些代码生成。
另一方面,您似乎正在实现自己的 Stream API 版本。除非您这样做是出于教育目的,否则使用现有且经过良好测试/记录的代码(尤其是标准 jdk 的代码部分)几乎总是比重新实现您自己的相同版本更好。
TA贡献1757条经验 获得超8个赞
我遇到的主要问题是任何pipe步骤都可能是终端操作。正如每个答案和主要帖子下面的讨论中所述:在java中不可能使用两次具有相同名称的函数并且一个是终端操作。
我猛烈抨击这个问题并尝试了多种方法,但每种方法都不起作用。那是当我意识到我在做的事情本质上与 Javas Stream-API 相同:你有一个起源(源),做一些花哨的东西(管道)然后结束(收集)。如果我们对我的问题应用相同的方案,则不需要进行pipe终端操作,我们只需要另一个操作(例如end)作为终点。由于我对何时可能结束(当前类型必须与另一种类型匹配)有一些扩展要求,因此我end只允许一个上下文特定的函数来实现,该函数只有一个可用的合理实现(很难解释)。这是当前实现的示例(pipe已重命名为和map):endto
Mapper<Person, PersonDTO> mapper = Datus.forTypes(Person.class, PersonDTO.class).immutable(PersonDTO::new)
.from(Person::getFirstName).to(ConstructorParameter::bind)
.from(Person::getLastName)
.given(Objects::nonNull, ln -> ln.toUpperCase()).orElse("fallback")
.to(ConstructorParameter::bind)
.build();
如您所见.to,充当终端操作员,ConstructorParameter::bind如果当前类型与预期类型不匹配,则会抱怨类型不匹配。
参见这里的to部分,这里的实现ConstructorParameter以及它是如何定义的。
添加回答
举报