简体   繁体   中英

How to get the symmetric difference between two Streams in Java 8?

假设我有两个相同类型的Java 8 Streams,如何有效地获得这两个Java 8 Streams的对称差异?

I wasn't able to find an efficient way of doing it. The best I managed was

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();
}

which is probably the solution you already came up with.

Even when trying to use stream operations to come up with the symmetric difference, I found myself having to produce lots of temporary streams and sets in order to get over the problem that I have to iterate over the streams multiple times. Here is a version that produces a Stream containing the symmetric difference, using only stream operations. You can see that it is far more inefficient.

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());
}

I'm putting this up because I'd be interested to see how it can be improved while retaining only stream operations (no Set or Collection operations apart from Collection.stream() ); and also how my clunky syntax can be improved.

As an aside, for people who are just getting into Java 8 and wondering where these classes are, my imports are:

import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM