有人能把这个非常简洁的Java函数分解成一个更详细的例子吗



我正试图将本Java教程移植到Xojo。我很难打开下面的Set函数,因为它虽然简短而优雅,但在一个小空间里却包含了大量转换,我不确定我是否正确理解了它。这很困难,因为Java不是我的主要语言,Xojo缺乏对泛型的支持:

public interface GraphNode {
String getId();
}

public class Graph<T extends GraphNode> {
private final Set<T> nodes;
private final Map<String, Set<String>> connections;
public T getNode(String id) {
return nodes.stream()
.filter(node -> node.getId().equals(id))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No node found with ID"));
}
public Set<T> getConnections(T node) {
return connections.get(node.getId()).stream()
.map(this::getNode)
.collect(Collectors.toSet());
}
}

我基本上只能计算出.stream()方法调用之前发生了什么:

  1. 获取通过的nodeGraphNodeId
  2. 从密钥与检索到的Id匹配的connectionsMap中获取Set<String>

我不明白的是这里发生了什么:

.map(this::getNode).collect(Collectors.toSet())

有人能提供伪代码来解释这一点吗?

它意味着mapidNode并将其放入(收集(set

this::getNode翻译为:从这个类中,在id上使用getNode,这只是.map(id -> getNode(id)).collect(Collectors.toSet())的语法糖

public T getNode(String id) {
return nodes.stream()
.filter(node -> node.getId().equals(id))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No node found with ID"));
}

此代码返回节点Set中具有id的第一个Node,nodes.stream() .filter(node -> node.getId().equals(id))将返回一个集合,其中每个节点都将id作为参数传递,findFirst()将返回集合中的第一个节点

public Set<T> getConnections(T node) {
return connections.get(node.getId()).stream()
.map(this::getNode)
.collect(Collectors.toSet());
}

由于connections是映射,connections.get(node.getId())将使用关键字node.getId()返回值,然后map(this::getNode)使用getNode(String id)将其从id映射到Node,最后将其放入set

流基本上为每个循环美化。通常,当您看到XXX.stream()或返回Stream<XXX>的方法时,它分别表示"对于XXX中的每件事"one_answers"对于每个XXX…"。

所以,这里说"对于Set<String>中的每个字符串…">

map的意思是"把每一件事都变成另一件事",换句话说,一个变换。对于for循环,它在伪代码中是这样的:

For Each x In set
f(x)
Next x

f是您传入的函数。在本例中,它是getNode

现在,getNode返回T,因此我们原始集合中的每个元素都已转换为T。最后一个调用是collect,意思是将所有这些元素放回某个集合或其他对象中。在这种情况下,我们将所有这些经过转换的T放回一个新的Set中。

伪代码中的整个代码将是:

originalSet = connections.get(node.getId())
newSet = []
For Each x In originalSet
newSet.add(x)
Next x

最新更新