在 Java 中扩展 ArrayList 时如何添加映射和过滤器?

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

我正在尝试创建一个扩展 ArrayListtable class。在其中,我希望能够创建一个 map 方法,该方法采用 lambda 表达式和 returns 一个具有映射值的新 table 。我也想用 filter 来做这个。我经常使用地图和过滤器,我不喜欢一遍又一遍地输入整个内容。

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?*/);
    }
}

我仍在努力弄清楚泛型。也许有更好的方法。我不知道。我曾尝试复制 ArrayList 的原始代码中的内容,但我尝试的一切似乎都会产生新问题。

一方面,完全有可能:

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() 可以实现,但它必须 return Table.

的特定子类型

另一方面,最好将列表作为 Table 字段 而不是扩展它:更喜欢组合而不是继承。您真的想要所有 ArrayList 方法可用吗?

只需将 Function<E, E> 用于映射器,因为您的 return 类型是相同的对象,并且将 Predicate<E> 用于谓词,因为 E 将被谓词。 对于 Table 任何实现 class 你有你在收集中使用。查看 collect 的工作方式。

它基本上需要一个初始化器 (first argument),BiFunction 来指定如何将元素添加到集合 (second argument),最后 BiFunction 来指定它在并行流的情况下如何工作(third argument)。请看下面的代码:-

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 {
//whatever you impl is
}

请随时将收集实现提取到 Collector 以避免代码重复。