Just use Function<E, E> for mapper, since your return type is the same object and Predicate<E> for the predicate how E should be specified. For a table of any implementation class, you have what you will use inside collect. See Method of collecting work.
It basically accepts an initializer ( first argument ), BiFunction, to indicate how to add an element to the collection ( second argument ), and finally BiFunction, to indicate how it works in the case of a parallel stream ( third argument ). See code below: -
public abstract class Table<E extends Element> extends ArrayList<E> { public Table<E> map(Function<E, E> mapper) { return this.stream().map(mapper).collect(TableImpl::new, TableImpl::add, TableImpl::addAll); } public Table<E> filter(Predicate<E> predicate) { return this.stream().filter(predicate).collect(TableImpl::new, TableImpl::add, TableImpl::addAll); } } class TableImpl extends Table {
Feel free to fetch the collect implementation on Collector to avoid code duplication.
Vinay prajapati
source share