Eri*_*lja 3 java functional-programming java-8
我不得不处理一些json,它可能有略微不同的格式(我只需要json数据的子集),我使用JsonPointer(来自Jackson)来查询json.我为这个问题编写了一个非功能性的解决方案,这对我有用,但我想尝试一种用于学习目的的功能方法.在下面的测试程序中,您可以看到我的两个解决方案.他们都工作,但功能解决方案变得非常冗长,我有一个恼人的警告来自Intellij关于使用get()而不使用isPresent检查.我想看看如何改进功能实现的建议,我很高兴看到使用第三方库的解决方案.我想,这里的基本问题是如何建模if-else-if-else,其中每个分支应以函数方式返回一些值.
@Test
public void testIt() {
ObjectMapper om = new ObjectMapper();
ImmutableList.of(
"{ \"foo\": { \"key\": \"1\" } }",
"{ \"bar\": { \"key\": \"1\" } }",
"{ \"key\": \"1\" }")
.forEach(str -> {
try {
System.out.println("Non-functional: " + getNode(om.readTree(str)));
System.out.println("Functional: " + getNodeFunc(om.readTree(str)));
} catch (Exception e) {
throw new RuntimeException("", e);
}
});
}
private JsonNode getNode(JsonNode parentNode) {
JsonPointer jp1 = JsonPointer.compile("/foo");
JsonPointer jp2 = JsonPointer.compile("/bar");
if (!parentNode.at(jp1).isMissingNode()) {
return parentNode.at(jp1);
} else if (!parentNode.at(jp2).isMissingNode()) {
return parentNode.at(jp2);
}
return parentNode;
}
private JsonNode getNodeFunc(JsonNode parentNode) {
BiFunction<JsonNode, String, Optional<JsonNode>> findNode = (node, path) -> {
JsonPointer jp = JsonPointer.compile(path);
return node.at(jp).isMissingNode() ? Optional.empty() : Optional.of(node.at(jp));
};
return findNode.apply(parentNode, "/foo")
.map(Optional::of)
.orElseGet(() -> findNode.apply(parentNode, "/bar"))
.map(Optional::of)
.orElse(Optional.of(parentNode))
.get(); // Intellij complains here: Optional.get() without isPresent check
}
Run Code Online (Sandbox Code Playgroud)
我会改写它
private JsonNode getNodeFunc2(JsonNode parentNode) {
return Stream.of(JsonPointer.compile("/foo"), JsonPointer.compile("/bar"))
.filter(i -> !parentNode.at(i).isMissingNode())
.findFirst()
.map(parentNode::at)
.orElse(parentNode);
}
Run Code Online (Sandbox Code Playgroud)
要么
private JsonNode getNodeFunc3(JsonNode parentNode) {
return Stream.of(JsonPointer.compile("/foo"), JsonPointer.compile("/bar"))
.map(parentNode::at)
.filter(Predicate.not(JsonNode::isMissingNode))
.findFirst()
.orElse(parentNode);
}
Run Code Online (Sandbox Code Playgroud)
要么
private JsonNode getNodeFunc4(JsonNode parentNode) {
return Stream.of("/foo", "/bar")
.map(JsonPointer::compile)
.map(parentNode::at)
.filter(Predicate.not(JsonNode::isMissingNode))
.findFirst()
.orElse(parentNode);
}
Run Code Online (Sandbox Code Playgroud)
因为这件作品
if (!parentNode.at(jp1).isMissingNode()) {
return parentNode.at(jp1);
} else if (!parentNode.at(jp2).isMissingNode()) {
return parentNode.at(jp2);
}
Run Code Online (Sandbox Code Playgroud)
是代码重复,可以通过循环整齐地处理:
for (JsonPointer jsonPointer : jsonPointers) {
JsonNode kid = parentNode.at(jsonPointer);
if (!kid.isMissingNode()) {
return kid;
}
}
Run Code Online (Sandbox Code Playgroud)