I have the following stream transform:
Stream.of(string1, string2)
.map(this::function1) // generate Stream<Pair<Integer, Integer>>
How to check the keys of the pairs are the same? Since I need to make sure they are the same before proceeding to the next step.
Well, the requirement looks like the one in this question, and Stuart Marks added an implementation to filter the stream based on distinct properties of an object.
This is his code:
public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { Set<Object> seen = ConcurrentHashMap.newKeySet(); return t -> seen.add(keyExtractor.apply(t)); }
However, we are not looking for filtering distinct values, but rather the opposite – object of which a specific property is the same as all others.
I adapted the code so it throws an exception if the specified property of one of the objects is different than the others:
static <T> Predicate<T> sameKeyOrThrow(Function<? super T, ?> keyExtractor, Supplier<RuntimeException> exceptionSupplier) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> {
seen.add(keyExtractor.apply(t));
if (seen.size() > 1) {
throw exceptionSupplier.get();
}
return true;
};
}
Usage:
Stream.of(string1, string2)
.map(this::function1)
.filter(sameKeyOrThrow(pair -> pair.left(), YourRuntimeException::new))
The advantage of this method compared to collecting using Collectors::groupingBy
is that it doesn't materialize the whole stream, but instead fails-fast if a distinct value is found.