有人可以将这个非常简洁的 Java 函数解压成一个更详细的示例吗?

Can someone unpack this very terse Java function into a more verbose example?

我正在尝试将 this Java tutorial 移植到 Xojo。我正在努力解压缩下面的 Set 函数,因为虽然它简短而优雅,但它把很多转换塞进了一个小的 space 中,我不确定我是否理解正确。这很难,因为 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. 得到传递的nodeId GraphNode
  2. connections Map 中获取 Set<String> 其键与检索到的 Id

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

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

有人可以提供伪代码来解释这个吗?

意思是mapid变成一个Node然后把它(收集)成一个set

this::getNode 转换为:从这个 class,在 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"));
    }

此代码return是节点集合中具有id的第一个节点,nodes.stream() .filter(node -> node.getId().equals(id))将return一个集合,其中每个节点都有id通过作为参数,findFirst() 将 return 集合中的第一个节点

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

因为 connections 是一个映射,connections.get(node.getId()) 将 return 带有键 node.getId() 的值,然后 map(this::getNode) 从 [=13= 映射它] 到 Node 使用 getNode(String id),最后把它变成 set

流基本上被美化了 for-each 循环。通常,当您看到 XXX.stream() 或 returns 一个 Stream<XXX> 的方法时,分别表示 "for each thing in XXX" 和 "For each XXX..."。

所以,这里说 "for each string in the Set<String>..."

map表示"turn each thing into something else",换句话说,变换。加上for循环,伪代码是这样的:

For Each x In set
    f(x)
Next x

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

现在,getNode returns T,所以我们原来集合中的每一个元素都变成了一个T。最后一个调用是 collect,这意味着将所有这些元素放回某个集合或某个其他对象中。在这种情况下,我们将所有这些转换后的 T 放回一个新的 Set.

伪代码中的整个代码为:

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