Java函数作为方法参数

时间:2016-01-31 13:55:34

标签: java graph

我正在使用一个表示为图形的系统。我经常需要以某种方式遍历图形,并对沿途传递的节点应用不同的操作。我想在类中实现遍历逻辑,然后将获得必须作为其提供的方法的输入参数应用的操作。像这样:

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是否可以将方法作为输入参数传递,如果是,那么正确的语法是什么?

3 个答案:

答案 0 :(得分:4)

Java 8及更高版本

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 7及以下

使用单个方法定义自己的接口,类似于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)

您可以浏览Functionhere是相同的基本用法。