How do I add map and filter when I extend ArrayList in Java?

MakPo :

I am trying to create a table class that extends ArrayList. In it, I would like to be able to create a map method that takes a lambda expression and returns a new table with the mapped values. I would also like to do this with filter. I use the map and filter a lot and I don't like typing out the whole thing over and over.

public abstract class Table<E extends Element> extends ArrayList<E> {
    // a lot of other stuff.

    public Table<E> map(/*WHAT DO I PUT HERE?*/ mapper) {
        return this.stream().map(mapper).collect(/*WHAT DO I PUT HERE?*/);
    }

    public Table<E> filter(/*WHAT DO I PUT HERE?*/ predicate) {
        return this.stream().filter(predicate).collect(/*WHAT DO I PUT HERE?*/);
    }
}

I am still trying to figure out generics. Maybe there is a better way. I don't know. I have tried duplicating what is in the original code for the ArrayList, but everything I try seems to create new problems.

Alexey Romanov :

On one hand, it's entirely possible:

public abstract class Table<E extends Element> extends ArrayList<E> {
    // implement in concrete subclasses
    public abstract <E1 extends Element> Collector<E1, ?, Table<E1>> collector();
    // Collector<E, ?, Table<E>> collector() is enough if map doesn't have E1 type parameter

    public <E1 extends Element> Table<E1> map(Function<E, E1> mapper) {
        return this.stream().map(mapper).collect(collector());
    }

    public Table<E> filter(Predicate<E> predicate) {
        return this.stream().filter(predicate).collect(collector());
    }
}

public class ChildTable<E extends Element> extends Table<E> {
    @Override
    public <E1 extends Element> Collector<E1, ?, Table<E1>> collector() {
        return Collectors.toCollection(() -> new ChildTable<E1>());
        // or simpler Collectors.toCollection(ChildTable::new);
    }
}

collector() could be implemented, but it would have to return a specific subtype of Table.

On the other, it may be better to have the list as a field of Table instead of extending it: prefer composition over inheritance. Do you really want all ArrayList methods available?

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=443331&siteId=1