假设我有两个相同类型的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.