我正在使用一个表示为图形的系统。我经常需要以某种方式遍历图形,并对沿途传递的节点应用不同的操作。我想在类中实现遍历逻辑,然后将获得必须作为其提供的方法的输入参数应用的操作。像这样:
class GraphTraverse{
public static void traverseAndApplyOperation(Graph graph, Node startNode, Function operationToApply){
// go through the graph and apply the input function (specified somewhere else) on the passed nodes
}
}
Java是否可以将方法作为输入参数传递,如果是,那么正确的语法是什么?
答案 0 :(得分:4)
Java 8使用java.util.function
中的预定义接口提供了很好的方法,具体取决于您想要的函数类型。
在您的情况下,您可能正在寻找一个Node
并且不返回任何内容的函数。在Java 8中,这称为Consumer<Node>
。
public static void traverseAndApplyOperation(Graph graph, Node startNode, Consumer<Node> operationToApply) {
// traversal logic with current node 'node'
operationToApply.accept(node); // use it this way
}
使用lambda表达式:
traverseAndApplyOperation(graph, startNode, node -> { /*do something here*/});
或者甚至更好,如果你有一个静态方法static void MyClass.myMethod(Node)
,你可以直接引用它:
traverseAndApplyOperation(graph, startNode, MyClass::myMethod);
如果Node
类中有非静态0-arg方法,它也有效:
traverseAndApplyOperation(graph, startNode, Node::myMethod);
使用单个方法定义自己的接口,类似于Java 8的Consumer<Node>
。
public interface NodeConsumer {
void accept(Node node);
}
然后你不能用lambda实例化它,但你仍然可以使用老式的方式:
traverseAndApplyOperation(graph, startNode, new NodeConsumer() {
@Override
public void accept(Node node) {
// do something here
}
});
答案 1 :(得分:2)
在Java 8中,您可以使用lambda表达式和方法引用来完成此任务:
class GraphTraverse{
public static void traverseAndApplyOperation(Graph graph, Node startNode, Consumer<Node> operation)
{
// pseudo code
for each element {
operation.accept(currentNode);
}
}
}
然后,你可以用不同的方式调用它:
使用lambda表达式:
traverseAndApplyOperation(graph, startNode, (Node node) -> { /* action */ });
traverseAndApplyOperation(graph, startNode, (node) -> { /* action */ });
traverseAndApplyOperation(graph, startNode, node -> { /* action */ });
traverseAndApplyOperation(graph, startNode, node -> /* single action */);
使用方法参考:
public static void applyOperation(Node n)
{
// a regular static method in the class
}
traverseAndApplyOperation(graph, startNode, ClientClass::applyOperation);
public void applyOperation(Node n)
{
// a regular dynamic method in the class
}
traverseAndApplyOperation(graph, startNode, this::applyOperation);
您可以这样做,因为java.util.function.Consumer<T>
是一个功能界面。它只是一个实现方法的接口,这些只是接口的匿名实现。然后,其他代码可以获得实现并调用它,就像它提供的那样。
如果您想了解更多信息,可能需要搜索&#34; lambda表达式&#34;,&#34;功能界面&#34;也许&#34;方法参考&#34;在Java 8中阅读一些文档。
答案 2 :(得分:1)