当我在Java中扩展ArrayList时,如何添加地图和过滤器?

时间:2018-03-17 18:53:41

标签: java generics arraylist java-8 extends

我正在尝试创建一个扩展table的{​​{1}}类。在其中,我希望能够创建一个ArrayList方法,该方法接受lambda表达式并返回带有映射值的新map。我还希望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?*/); } } 原始代码中的内容,但我尝试的所有内容似乎都会产生新的问题。

2 个答案:

答案 0 :(得分:8)

一方面,它完全有可能:

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()可以实现,但必须返回Table的特定子类型。

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

答案 1 :(得分:3)

只需将const img = new Image() const canvas = document.createElement('canvas') img.src = 'https://cmeimg-a.akamaihd.net/640/clsd/getty/991dda07ecb947f1834bf1aa89153cf6' const newWidth = 200 const newHeight = 200 const startX = 200 const startY = 100 img.onload = () => { canvas.width = newWidth; canvas.height = newHeight; canvas.getContext('2d').drawImage(img, startX, startY, newWidth, newHeight, 0, 0, newWidth, newHeight); } document.body.appendChild(canvas) document.body.appendChild(img)用于mapper,因为您的返回类型是同一个对象,谓词的Function<E, E>Predicate<E>的谓词。 对于Table,无论您使用哪种实现类,都可以在collect中使用。看收集的方式。

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

second argument

请随时将收集实施提取到third argument,以避免重复代码。