gpt4 book ai didi

java - 我将如何组合 BiPredicate 和 Predicate?

转载 作者:搜寻专家 更新时间:2023-10-31 08:22:34 25 4
gpt4 key购买 nike

我有两个 lambda 函数(谓词):

final Predicate<Node> isElement = node -> node.getNodeType() == Node.ELEMENT_NODE;
final BiPredicate<Node, String> hasName = (node, name) -> node.getNodeName().equals(name);

我想以某种简洁的方式组合起来,像这样:

// Pseudocode
isElement.and(hasName("tag")) // type of Predicate

然后传递给另一个lambda函数:

final BiFunction<Node, Predicate<Node>, List<Node>> getChilds = (node, cond) -> {
List<Node> resultList = new ArrayList<>();
NodeList nodeList = node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); ++i) {
Node tmp = nodeList.item(i);
if (cond.test(tmp)) {
resultList.add(tmp);
}
}
return resultList;
};

因此,我希望它看起来像下面这样:

List<Node> listNode = getChilds.apply(document, isElement.and(hasName("tag")));

但是Predicate方法不接受BiPredicate参数。

我该怎么做?

最佳答案

停止将每个方法重写为 lambda 表达式。没有真正的好处。如果你有一个普通的方法,你可以通过它的简单名称来调用它,而不必附加 applytest 或类似的。如果您真的需要一个函数,您仍然可以使用 :: 运算符创建一个静态方法引用。

因此,如果您想改进代码,请考虑使用新的 API 而不是过度使用 Java 语言功能。例如:

static List<Node> getChilds(Node node, Predicate<Node> cond) {
NodeList nodeList = node.getChildNodes();
return IntStream.range(0, nodeList.getLength()).mapToObj(nodeList::item)
.filter(cond).collect(Collectors.toList());
}

关于您尝试组合 Predicate。当然,您可以毫不妥协地将所有内容表达为函数。例如:

Predicate<Node> isElement = node -> node.getNodeType() == Node.ELEMENT_NODE;
Function<Node, String> nodeName = Node::getNodeName;
Predicate<Node> both = isElement.and(nodeName.andThen("tag"::equals)::apply);

但这真的是一种进步吗?

你可以简单地写

Predicate<Node> both = isElement.and(n -> n.getNodeName().equals("tag"));

或者,甚至更简单,因为 Node 不代表 ELEMENT 节点永远不会报告 "tag" 的节点名称,您不需要需要第一个谓词,整个操作变成:

getChilds(document, n -> "tag".equals(n.getNodeName()));

这可能不像复杂的函数组合那样花哨,但它是一个实用解决方案。

关于java - 我将如何组合 BiPredicate 和 Predicate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30798600/

25 4 0