如何在Java 8中获得两个Streams之间的对称差异?

时间:2014-10-24 11:47:58

标签: java java-8 java-stream

鉴于我有两个相同类型的Java 8 Streams,如何有效地将这两者的对称差异作为新流?

1 个答案:

答案 0 :(得分:1)

我无法找到一种有效的方法。我管理的最好的是

static <T> Stream<T> symmetricDifference(Stream<T> stream1, Stream<T> stream2) {
    Set<T> elements1 = stream1.collect(Collectors.toSet());
    Set<T> elements2 = stream2.collect(Collectors.toSet());
    Set<T> result = new HashSet<T>(elements1);
    result.addAll(elements2);
    elements1.retainAll(elements2);
    result.removeAll(elements1);
    return result.stream();
}

这可能是你已经提出的解决方案。

即使尝试使用流操作来提出对称差异,我发现自己必须生成大量临时流和集合才能克服我必须多次迭代流的问题。这是一个只使用流操作生成包含对称差异的Stream的版本。你可以看到效率低得多。

static <T> Stream<T> disjointStream(Stream<T> stream1, Stream<T> stream2) {
    Set<T> elements1 = stream1.collect(Collectors.toSet());
    Set<T> elements2 = stream2.collect(Collectors.toSet());
    Set<T> elementsIn1Notin2 = elements1.stream().filter(t -> !elements2.stream().anyMatch(Predicate.isEqual(t))).collect(Collectors.toSet());
    Set<T> elementsIn2Notin1 = elements2.stream().filter(t -> !elements1.stream().anyMatch(Predicate.isEqual(t))).collect(Collectors.toSet());
    return Stream.concat(elementsIn1Notin2.stream(), elementsIn2Notin1.stream());
}

我提出这个问题是因为我有兴趣了解如何在仅保留流操作的情况下改进它(除了Set之外没有CollectionCollection.stream()操作);以及如何改进我笨重的语法。

顺便说一下,对于刚刚进入Java 8并想知道这些类在哪里的人来说,我的导入是:

import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
相关问题