在 Java 中扩展 ArrayList 时如何添加映射和过滤器?
How do I add map and filter when I extend ArrayList in Java?
我正在尝试创建一个扩展 ArrayList
的 table
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
以避免代码重复。
我正在尝试创建一个扩展 ArrayList
的 table
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
以避免代码重复。