Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.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流在循环中的使用_Java_Java Stream - Fatal编程技术网

Java流在循环中的使用

Java流在循环中的使用,java,java-stream,Java,Java Stream,我对java流相当陌生。我是否每次都需要在这个循环中重新创建流,或者有更好的方法来实现这一点?创建一次流并使用.noneMatch两次会导致“流已关闭”异常 for ( ItemSetNode itemSetNode : itemSetNodeList ) { Stream<Id> allUserNodesStream = allUserNodes.stream().map( n -> n.getNodeId() ); Id nodeId = itemSetNode.

我对java流相当陌生。我是否每次都需要在这个循环中重新创建流,或者有更好的方法来实现这一点?创建一次流并使用.noneMatch两次会导致“流已关闭”异常

for ( ItemSetNode itemSetNode : itemSetNodeList )
{
  Stream<Id> allUserNodesStream = allUserNodes.stream().map( n -> n.getNodeId() );

  Id nodeId = itemSetNode.getNodeId();
  //if none of the user node ids match the node id, the user is missing the node
  if ( allUserNodesStream.noneMatch( userNode -> userNode.compareTo( nodeId ) == 0 ) )
  {
    isUserMissingNode = true;
    break;
  }
}
for(ItemSetNode ItemSetNode:itemSetNodeList)
{
Stream AlluserNodeStream=allUserNodes.Stream().map(n->n.getNodeId());
Id nodeId=itemSetNode.getNodeId();
//如果没有一个用户节点id与节点id匹配,则该用户缺少该节点
if(AllUserNodeStream.noneMatch(userNode->userNode.compareTo(nodeId)==0))
{
isUserMissingNode=true;
打破
}
}

谢谢大家!

我建议您列出循环之外的所有用户ID。只需确保类
Id
覆盖
equals()
函数

List<Id> allUsersIds = allUserNodes.stream().map(n -> n.getNodeId()).collect(Collectors.toList());

for (ItemSetNode itemSetNode : itemSetNodeList)
{
    Id nodeId = itemSetNode.getNodeId();

    if (!allUsersIds.contains(nodeId))
    {
        isUserMissingNode = true;
        break;
    }
}
List allUsersIds=allUserNodes.stream().map(n->n.getNodeId()).collect(Collectors.toList());
for(ItemSetNode ItemSetNode:itemSetNodeList)
{
Id nodeId=itemSetNode.getNodeId();
如果(!allUsersIds.contains(nodeId))
{
isUserMissingNode=true;
打破
}
}

流的终端操作,如
noneMatch()
关闭流,使其不再可重用。
如果需要重用此流:

Stream<Id> allUserNodesStream = allUserNodes.stream().map( n -> n.getNodeId() );
现在请记住,流在编译后会变成字节码中的循环。
可能不希望多次执行同一循环。因此,在实例化多个相同流之前,应该考虑这一点。
作为创建多个流以检测与nodeId匹配的替代方法:

if (allUserNodesStream.noneMatch( userNode -> userNode.compareTo( nodeId ) == 0 ) ) {
  isUserMissingNode = true;
  break;
}
而是使用类型为
Set
的结构,其中包含
allUserNodes
的所有
id

if (idsFromUserNodes.contains(nodeId)){
  isUserMissingNode = true;
  break;
}
这将使逻辑更简单,性能更好。

当然,它假定
compareTo()
equals()
一致,但强烈建议(尽管不是必需的)。

以下代码应该是等效的,除非布尔值是反向的,因此如果缺少节点,则为
false

首先,将所有用户节点Id收集到
TreeSet
(如果
Id
实现了
hashCode()
equals()
,则应使用
HashSet
)。然后,我们对
itemSetNodeList
进行流式处理,以查看这些节点ID是否都包含在集合中

TreeSet<Id> all = allUserNodes
                        .stream()
                        .map(n -> n.getNodeId())
                        .collect(Collectors.toCollection(TreeSet::new));

boolean isAllNodes = itemSetNodeList
                        .stream()
                        .allMatch(n -> all.contains(n.getNodeId()));
TreeSet all=allUserNodes
.stream()
.map(n->n.getNodeId())
.collect(收集器.toCollection(TreeSet::new));
布尔值isAllNodes=itemSetNodeList
.stream()
.allMatch(n->all.contains(n.getNodeId());
有很多方法可以编写等价的(至少对外人而言)代码,这使用
集合来改进查找,因此我们不需要不断迭代
allUserNodes
集合


您希望避免在循环中使用流,因为当您在其中执行线性循环和线性流操作时,这将使您的算法变成
O(n²)
。这种方法是
O(n logn)
,用于线性流操作和
O(logn)
TreeSet
查找。使用
HashSet
这可以归结为
O(n)
,除非处理大量元素,否则这并不重要。

您也可以这样做:

Set<Id> allUserNodeIds = allUserNodes.stream()
    .map(ItemSetNode::getNodeId)
    .collect(Collectors.toCollection(TreeSet::new));
return itemSetNodeList.stream()
    .anyMatch(n -> !allUserNodeIds.contains(n.getNodeId())); // or firstMatch
Set allUserNodeIds=allUserNodes.stream()
.map(ItemSetNode::getNodeId)
.collect(收集器.toCollection(TreeSet::new));
return itemSetNodeList.stream()
.anyMatch(n->!allUserNodeIds.contains(n.getNodeId());//还是第一场比赛
甚至:

Collectors.toCollection(() -> new TreeSet<>(new YourComparator()));
collector.toCollection(()->newtreeset(newyourcomarator());

它将从itemSetNodeList中获取每个项目,并使用noneMatch()检查它是否存在于中。如果不存在,则返回true。如果至少有一次未找到项,则anyMatch将停止搜索并返回false。如果找到所有项,我们将返回true

Stream<Id> allUserNodesStream = allUserNodes.stream().map( n -> n.getNodeId() );
            boolean isUserMissing=itemSetNodeList.stream()
                            .anyMatch(n-> allUserNodes.stream().noneMatch(n));
Stream allUserNodesStream=allUserNodes.Stream().map(n->n.getNodeId());
布尔值isUserMissing=itemSetNodeList.stream()
.anyMatch(n->allUserNodes.stream().noneMatch(n));

这似乎不是使用流的最佳情况。我会使用
TreeSet
(因为
Id
似乎实现了
Comparable
)或
HashSet
。你能举一个如何使用TreeSet的例子吗?您将遍历集合并将其转换为树集,然后对每个元素使用set.contains()?再次流式处理。。。此外,供应商比方法更适合。当您回答这个问题时,您还可以提供一种可能不会做太多工作的非流方式,除非
allUserNodes
可以在循环时更改,否则没有理由多次执行lambda。@Eugene我更新了一个集合,我认为在这里更有意义。关于
供应商
,为什么它更适合?我不确定是否能得到它。根据他的代码(有break for true),他不需要allMatch。@Egorlitvineko那是因为我翻转了(代码)逻辑。逻辑是“每个itemSetNode是否包含在allUserNodes中?”,这在反向逻辑版本中实际上更清楚。这里的逻辑失败。如果
allUserNodes
中存在一个
itemSetNodeList
,则返回true。如果
allUserNodes
中不存在
itemSetNodeList
中的任何一个,则不会。我与作者的条件相反。“如果A,则所有元素均不匹配”逻辑上等于“如果不是A,则元素中至少有一个匹配”。如果你仔细观察,我会返回true,即使其中一个itemSetNodeList不存在于allUserNodes中。啊,你说得对,我错过了否定。当你开始颠倒逻辑的时候是很棘手的。是的,我同意你的看法。javast中的可读否定
Collectors.toCollection(() -> new TreeSet<>(new YourComparator()));
Stream<Id> allUserNodesStream = allUserNodes.stream().map( n -> n.getNodeId() );
            boolean isUserMissing=itemSetNodeList.stream()
                            .anyMatch(n-> allUserNodes.stream().noneMatch(n));