有人可以将这个非常简洁的 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()
方法调用之前发生了什么:
- 得到传递的
node
的Id
GraphNode
- 从
connections
Map
中获取 Set<String>
其键与检索到的 Id
我不明白的是这里发生了什么:
.map(this::getNode).collect(Collectors.toSet())
有人可以提供伪代码来解释这个吗?
意思是map
把id
变成一个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
我正在尝试将 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()
方法调用之前发生了什么:
- 得到传递的
node
的Id
GraphNode
- 从
connections
Map
中获取Set<String>
其键与检索到的Id
我不明白的是这里发生了什么:
.map(this::getNode).collect(Collectors.toSet())
有人可以提供伪代码来解释这个吗?
意思是map
把id
变成一个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