Is it possible perform multiple mapping on collection? Following code compilation error:
... in Stream cannot be applied to
java.util.function.Function<capture<?>,capture<?>>
private static List<?> multipleMapping(final Collection<?> collection, final List<Function<?, ?>> functions) {
Stream<?> stream = collection.stream();
for (Function<?, ?> function : functions) {
stream = stream.map(function);
}
return stream.collect(Collectors.toList());
}
I would like to generic solution.
Now, you can invoke your multipleMapping() method with the list of candidates and the composed function : List<Integer> scores = multipleMapping(candidates, function);
Introduced in Java 8, the Stream API is used to process collections of objects. A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result. A stream is not a data structure instead it takes input from the Collections, Arrays or I/O channels.
In Java 8 Streams, the flatMap() method applies operation as a mapper function and provides a stream of element values. It means that in each iteration of each element the map() method creates a separate new stream. By using the flattening mechanism, it merges all streams into a single resultant stream.
map() function produces one output for one input value, whereas flatMap() function produces an arbitrary no of values as output (ie zero or more than zero) for each input value.
The problem comes from the fact that you're using a generic wildcard ?
. What you want is to have a parameterized type T
, that will represent the type of the Stream element. Assuming the function would return the same type as their input, you could have:
private static <T> List<T> multipleMapping(final Collection<T> collection, final List<Function<T, T>> functions) {
Stream<T> stream = collection.stream();
for (Function<T, T> function : functions) {
stream = stream.map(function);
}
return stream.collect(Collectors.toList());
}
This compiles fine: the mapper given to map
correcly accepts a T
and returns a T
. However, if the functions don't return the same type as their input then you won't be able to keep type-safety and will have to resort to using List<Function<Object, Object>>
.
Note that we could use a UnaryOperator<T>
instead of Function<T, T>
.
Also, you could avoid the for
loop and reduce all functions into a single one using andThen
:
private static <T> List<T> multipleMapping(final Collection<T> collection, final List<Function<T, T>> functions) {
return collection.stream()
.map(functions.stream().reduce(Function.identity(), Function::andThen))
.collect(Collectors.toList());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With