应封装而非修改JDK集合,设计FluentList等链式集合包装类,内部持有ArrayList并让操作方法返回this,支持filter、map等连续调用,终结方法如toList()提取结果,兼顾安全性与可扩展性。

直接用 return this 优化集合处理,关键不是给 ArrayList 或 HashMap 加链式方法,而是设计专门的可流式操作的集合封装类——它内部持有标准集合,对外提供返回自身、支持连续调用的配置与操作方法。
为什么不能直接改写 JDK 集合?
JDK 中的 ArrayList、HashMap 等类方法都返回 void 或新对象(如 subList 返回新 List),且源码不可修改。强行继承并重写方法会破坏契约、引发类型不安全,也不符合开闭原则。正确做法是封装而非侵入。
- 继承 ArrayList 并让 add() 返回 this:编译失败——add 原签名是 boolean,子类无法协变返回 ArrayList
- 用装饰器模式包装:可安全扩展,保持 JDK 集合稳定性
- 目标不是“让 ArrayList 支持链式”,而是“提供一个链式友好的集合操作入口”
设计一个 FluentList 封装器
创建轻量级包装类,内部持有一个 ArrayList,所有添加、过滤、转换操作都返回 this,并允许最终提取或消费:
- 构造时传入泛型类型,如 new FluentList<String>()
- add()、addAll()、removeIf() 等状态变更方法返回 FluentList<T>,支持连续调用
- 提供终结方法:toList() 返回原始 ArrayList,forEach() 执行遍历,mapTo() 转为其他结构
- 示例:new FluentList<Integer>().add(1).add(2).filter(x -> x > 0).map(x -> x * 2).toList()
配合函数式接口提升表达力
链式操作的价值,在于把数据流逻辑显式串起来。FluentList 可内置常见函数式行为:
立即学习“Java免费学习笔记(深入)”;
- filter(Predicate):保留满足条件的元素,仍返回 FluentList
- map(Function):转换每个元素,内部生成新列表但封装回当前实例(或复用底层 list)
- distinct() / sorted():基于 Stream 操作后重建内部 list 并 return this
- 避免副作用:像 forEach(Consumer) 应作为终结方法,不返回 this;否则语义混淆(“执行完还继续链?”)
注意线程安全与可变性边界
return this 意味着所有操作作用于同一实例,这带来便利也带来风险:
- 多线程并发调用同一个 FluentList 实例?需手动同步或声明为不可共享
- 若需不可变语义(如配置后禁止再改),可在 build() 后置 flag,后续调用抛 UnsupportedOperationException
- 不要在链式方法中返回 Collections.unmodifiableList(...) —— 它中断链;应返回新的 FluentList 包装实例
- 调试时单步进入 .filter().map().toList() 一行,可用 IDE “Step Into” 逐方法跟踪,或拆成多行提升可读性


















