Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java函数接口澄清-传递到lambda表达式的参数_Java_Lambda_Functional Interface - Fatal编程技术网

Java函数接口澄清-传递到lambda表达式的参数

Java函数接口澄清-传递到lambda表达式的参数,java,lambda,functional-interface,Java,Lambda,Functional Interface,我有下面的代码,我正在努力理解。我有一个接口声明如下: public interface WeightedRelationshipConsumer { boolean accept(int sourceNodeId, int targetNodeId, long relationId, double weight); } public interface WeightedRelationshipIterator { void forEachRelationship(int no

我有下面的代码,我正在努力理解。我有一个接口声明如下:

public interface WeightedRelationshipConsumer {
    boolean accept(int sourceNodeId, int targetNodeId, long relationId, double weight);
}
public interface WeightedRelationshipIterator {
    void forEachRelationship(int nodeId, Direction direction, WeightedRelationshipConsumer consumer);
}
然后我有第二个接口,它接受
WeightedRelationshipConsumer
声明如下:

public interface WeightedRelationshipConsumer {
    boolean accept(int sourceNodeId, int targetNodeId, long relationId, double weight);
}
public interface WeightedRelationshipIterator {
    void forEachRelationship(int nodeId, Direction direction, WeightedRelationshipConsumer consumer);
}
在Dijkstra算法的实现中,我有以下代码:

private void run(int goal, Direction direction) {
        // `queue` is a Priority Queue that contains the vertices of the graph
        while (!queue.isEmpty()) {
            int node = queue.pop();
            if (node == goal) {
                return;
            }
            // `visited` is a BitSet.
            visited.put(node);
            // Gets the weight of the distance current node from a node-distance map.
            double costs = this.costs.getOrDefault(node, Double.MAX_VALUE);
            graph.forEachRelationship(
                    node,
                    direction, (source, target, relId, weight) -> {
                        updateCosts(source, target, weight + costs);
                        if (!visited.contains(target)) {
                            queue.add(target, 0);
                        }
                        return true;
                    });
        }
    }
这是最重要的

graph.forEachRelationship(node, direction, (source, target, relId, weight) -> {
   updateCosts(source, target, weight + costs);
   if (!visited.contains(target)) {
       queue.add(target, 0);
   }
   return true;
});
这使我困惑。具体来说,什么是
目标
relId
权重
,它们是如何解决的?这4个变量没有在这个类中的任何其他地方定义<代码>更新成本()如下所示:

private void updateCosts(int source, int target, double newCosts) {
    double oldCosts = costs.getOrDefault(target, Double.MAX_VALUE);
    if (newCosts < oldCosts) {
        costs.put(target, newCosts);
        path.put(target, source);
    }
}
private void updateCosts(int源、int目标、双倍新成本){
double oldCosts=costs.getOrDefault(目标,double.MAX_值);
如果(新成本<旧成本){
成本。卖出(目标,新成本);
path.put(目标、源);
}
}

此外,如果有可能有助于理解此类代码的资源,请提供。谢谢。

您的界面似乎是一个功能界面:

interface WeightedRelationshipConsumer {
  boolean accept(int sourceNodeId, int targetNodeId, long relationId, double weight);
}
这些类型也称为SAM类型(单一抽象方法类型),它们是使用lambda表达式或方法引用实现的候选类型

lambda表达式是实现接口唯一方法的一种方法

比如说

WeightedRelationshipConsumer wrc = (source, target, relId, weight) -> true;
这是一种为其
accept
方法提供实现的方法,其中
(源、目标、relId、权重)
对应于方法的声明参数,其中
true
,lambda表达式的返回值,也对应于
accept
方法的返回类型

它显示您的
图形。forEachRelationship
方法接受
WeightedRelationshipConsumer
的实例作为其第三个参数,因此,您可以将lambda表达式作为参数传递

正如你的问题所述:

graph.forEachRelationship(node, direction, (source, target, relId, weight) -> {
   updateCosts(source, target, weight + costs);
   if (!visited.contains(target)) {
       queue.add(target, 0);
   }
   return true;
});
关于参数的明显缺乏定义,这只是您的一个困惑。Lambda表达式支持类型推断,因此,我们不需要再次提供参数的类型,毕竟它们已经在Lambda表达式实现的方法的签名中声明(即,
accept

因此,我们之前的lambda可以声明为:

WeightedRelationshipConsumer wrc = (int sourceNodeId, int targetNodeId, long relationId, double weight) -> true
但为了使它们更具可读性,通常会省略这些类型。毕竟,编译器可以从
accept
的方法签名推断参数的类型

因此,lambda括号中的标识符列表实际上是函数的参数声明


这里有大量的参考资料,在Stackoverflow的标签下

谢谢。
目标
relId
权重的实际定义如何
updateCosts()
需要它们,但是,我看不到它们在任何地方被定义。@我只是扩展了我的答案以解决您的问题。谢谢,我有最后一个澄清。关于
forEachRelationship()
这是一个抽象方法,当参数传递给它时,实际会发生什么?我在任何地方都看不到它的函数体。我想这就是我困惑的原因。请帮我澄清一下,我会接受你的回答。非常感谢。@swdon您没有提供
forEachRelationship
方法声明的详细信息,它的类及其派生,那么我怎么知道您问题的答案呢?但是,我可以从中推断,即使引用
来自某个抽象类型,它显然指向了该抽象的实现,其中确实定义了
forEachRelationship
方法。如果您得到的是
graph.getClass()
,那么您可能会找到这个派生类是什么。