2014-01-23 48 views
2

我想执行一个流,其中来自流的输出然后被用作相同流中的源的相同操作中的源。Java 8迭代流操作

我目前使用队列执行这种操作;我删除一个项目,处理它,并将任何需要进一步处理的结果添加回队列。这里有这样的事情的两个例子:

Queue<WorkItem> workQueue = new Queue<>(workToDo); 
while(!workQueue.isEmpty()){ 
    WorkItem item = workQueue.remove(); 
    item.doOneWorkUnit(); 
    if(!item.isDone()) workQueue.add(item); 
} 

Queue<Node> nodes = new Queue<>(rootNodes); 
while(!nodesLeft.isEmpty()){ 
    Node node = nodes.remove(); 
    process(node); 
    nodes.addAll(node.children()); 
} 

我猜想,第一可以同时这样进行:

try { 
    LinkedBlockingQueue<WorkItem> workQueue = new LinkedBlockingQueue<>(); 
    Stream<WorkItem> reprocess = Stream.generate(() -> workQueue.remove()).parallel(); 

    Stream.concat(workToDo.parallelstream(), reprocess) 
      .filter(item -> {item.doOneWorkUnit(); return !item.isDone();}) 
      .collect(Collectors.toCollection(() -> workQueue)); 
} catch (NoSuchElementException e){} 

,第二个作为:

try { 
    LinkedBlockingQueue<Node> reprocessQueue = new LinkedBlockingQueue<>(); 
    Stream<WorkItem> reprocess = Stream.generate(() -> nodes.remove()).parallel(); 

    Stream.concat(rootNodes.parallelStream(), reprocess) 
      .filter(item -> {process(item); return true;}) 
      .flatMap(node -> node.children().parallelStream()) 
      .collect(Collectors.toCollection(() -> reprocessQueue)); 
} catch (NoSuchElementException e){} 

然而,这些感觉像kludgy解决方法,我不喜欢使用异常。有没有人有更好的方式来做这种事情?

+1

如果你能以任何方式完成这项工作,我会坦然相当惊讶。我不希望这个工作。 –

+0

我同意路易斯。它只是不符合流模式。 –

+0

你为什么不把两个操作的组合作为一个操作?我的意思是,如果你想做一些像'x; y = f(x); z = f(y);返回z',那么你可以只返回f(f(x))'。 – tkroman

回答

1

为了使工作平行,我会使用标准java.util.concurrent.Executor。要将任务返回到工作队列,请在每个任务的代码末尾添加executor.execute(this)