可以选择在Streams API函数调用链的中间部分调用`.distinct()`。

huangapple go评论97阅读模式
英文:

Optionally call .distinct() in the middle of a Streams API function call chain

问题

我找不到同时使用Streams API和在聚合操作的“pipeline”中进行简短条件添加(例如.distinct()调用)的方法。

以下代码显示了我在条件性的.distinct()调用后不得不重复.filter调用,使代码比我想要的更冗长:

AtomicInteger index = new AtomicInteger();
Supplier<Stream<NodeXType>> nodexSupplier = () -> myXMLPayload.getNodeXs().stream();
// 避免BUG,其中NodeXs在影响测试的情况下在Payload XML中重复。
if (NODE_X.length < nodexSupplier.get().filter(e -> e.getSubTypeofNode_X().equalsIgnoreCase("myTargetValue")).count()){
    LOGGER.log(Level.WARNING, "had more sub-type values than expected, so removed duplicates");
    nodexSupplier.get()
        .distinct()
        .filter(e -> e.getSubTypeofNode_X().equalsIgnoreCase("myTargetValue"))
        .forEachOrdered(e -> {
            assertEquals(" myTargetValue nodes not updated to expected value",
                e.getSubTypeofNode_X().getNewValue().toString(), NODE_X[index.getAndIncrement()]);
        });
} else {
    nodexSupplier.get()
        .filter(e -> e.getSubTypeofNode_X().equalsIgnoreCase("myTargetValue"))
        .forEachOrdered(e -> {
            assertEquals(" myTargetValue nodes not updated to expected value",
                e.getSubTypeofNode_X().getNewValue().toString(), NODE_X[index.getAndIncrement()]);
        });
}

是否有一种方法可以避免这种情况,而不违反Streams的规则?
像这样:

pipelineObj = Source.stream()    
if (condition) {pipelineObj.distinct}
pipelineObj.filter{}...
英文:

I cannot find a way to use the Streams API and to have a short conditional addition to the 'pipeline' of an aggregate operation like a .distinct() call.

The following code shows how I have to duplicate the .filter call after the conditional .distinct() call, making the code more verbose than I'd like:

AtomicInteger index = new AtomicInteger();
Supplier&lt;Stream&lt;NodeXType&gt;&gt; nodexSupplier = () -&gt; myXMLPayload.getNodeXs().stream();
// Avoid BUG where the NodeXs are duplicated in the Payload XML impacting tests.
if (NODE_X.length &lt; nodexSupplier.get().filter(e -&gt; e.getSubTypeofNode_X().equalsIgnoreCase(&quot;myTargetValue&quot;)).count()){
   LOGGER.log(Level.WARNING, &quot;had more sub-type values than expected, so removed duplicates&quot;);
   nodexSupplier.get()
       .distinct()
       .filter(e -&gt; e.getSubTypeofNode_X().equalsIgnoreCase(&quot;myTargetValue&quot;))
       .forEachOrdered(e -&gt; {
           assertEquals(&quot; myTargetValue nodes not updated to expected value&quot;,
               e.getSubTypeofNode_X().getNewValue().toString(), NODE_X[index.getAndIncrement()]);
       });
} else {
   nodexSupplier.get()
       .filter(e -&gt; e.getSubTypeofNode_X().equalsIgnoreCase(&quot;myTargetValue&quot;))
       .forEachOrdered(e -&gt; {
           assertEquals(&quot; myTargetValue nodes not updated to expected value&quot;,
               e.getSubTypeofNode_X().getNewValue().toString(), NODE_X[index.getAndIncrement()]);
       });
}

Is there a way to avoid this, without breaking the Streams rules?
like:

pipelineObj =  Source.stream()    
if (condition) {pipelineObj.distinct}
pipelineObj.filter{}...

答案1

得分: 5

只要在单个流上不多次执行终端操作,将流放入变量中是可以的:

Stream<NodeXType> pipelineObj = nodexSupplier.get();
if (NODE_X.length < pipelineObj.filter(e -> e.getSubTypeofNode_X().equalsIgnoreCase("myTargetValue")).count()) {
    pipelineObj = pipelineObj.distinct();
}
pipelineObj
    .filter(e -> e.getSubTypeofNode_X().equalsIgnoreCase("myTargetValue"))
    .forEachOrdered(e -> {
        assertEquals(" myTargetValue节点未更新为预期值",
            e.getSubTypeofNode_X().getNewValue().toString(), NODE_X[index.getAndIncrement()]);
    });

不过,你可能想要解决关于两次调用nodexSupplier.get()的问题...

英文:

As long as you don't do terminal operations multiple times on a single stream, it's okay to put the stream into a variable:

Stream&lt;NodeXType&gt; pipelineObj = nodexSupplier.get();
if (NODE_X.length &lt; nodexSupplier.get().filter(e -&gt; e.getSubTypeofNode_X().equalsIgnoreCase(&quot;myTargetValue&quot;)).count()) {
    pipelineObj = pipelineObj.distinct();
}
pipelineObj
    .filter(e -&gt; e.getSubTypeofNode_X().equalsIgnoreCase(&quot;myTargetValue&quot;))
    .forEachOrdered(e -&gt; {
           assertEquals(&quot; myTargetValue nodes not updated to expected value&quot;,
               e.getSubTypeofNode_X().getNewValue().toString(), NODE_X[index.getAndIncrement()]);
       });

However, you might want to do something about calling nodexSupplier.get() twice...

答案2

得分: 2

写一个实用方法

```java
static <T> Stream<T> distinctIf(Stream<T> s, boolean b) {
  return b ? s.distinct() : s;
}
英文:

Write a utility method:

static &lt;T&gt; Stream&lt;T&gt; distinctIf(Stream&lt;T&gt; s, boolean b) {
  return b ? s.distinct() : s;
}

huangapple
  • 本文由 发表于 2020年10月24日 22:25:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/64514376.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定