I have written a few simple-to-be-used methods in Java 8, and am wondering what could be improved upon those:
public static <E, R, C extends Collection<? extends R>> C transform(final Collection<E> collection, final Function<? super E, ? extends R> mapper) {
try {
Objects.requireNonNull(collection);
Objects.requireNonNull(mapper);
Class<? extends Collection> clazz = collection.getClass();
@SuppressWarnings("unchecked") Collection<Object> returnCollection = clazz.newInstance();
collection.stream().map(mapper).forEach(returnCollection::add);
@SuppressWarnings("unchecked") C genericReturnCollection = (C)returnCollection;
return genericReturnCollection;
} catch (InstantiationException | IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
public static <E, R, C extends Collection<R>> C transform(final Collection<E> collection, final Function<? super E, ? extends R> mapper, final Supplier<C> collectionSupplier) {
Objects.requireNonNull(collection);
Objects.requireNonNull(mapper);
Objects.requireNonNull(collectionSupplier);
return collection.stream().map(mapper).collect(Collectors.toCollection(collectionSupplier));
}
Their purpose is to provide similar functionality as the List.replaceAll()
method, but then allowing that the mapped type differs from the original type. Hence it is something that should be in a static
factory class, as it will always need to create a new collection.
Some example code:
LinkedList<Integer> linkedList = new LinkedList<>();
linkedList.add(5);
linkedList.add(10);
linkedList.add(15);
LinkedList<String> resultList = transform(linkedList, i -> (i + 1) + "-" + i);
and
LinkedList<Integer> linkedList = new LinkedList<>();
linkedList.add(5);
linkedList.add(10);
linkedList.add(15);
LinkedList<String> resultList = transform(linkedList, i -> (i + 1) + "-" + i, LinkedList::new);
Both have as output:
6-5
11-10
16-15
I am aware that the transform
with a Supplier<C>
as argument is obviously much nicer, however for convienience the single-argument version with only a function is much better.