java自定义集合实现变动监听的核心是显式收口修改操作并在入口触发通知,结合观察者模式解耦;需定义泛型collectionlistener接口与collectionevent事件,重写arraylist的mutator方法嵌入通知点,支持多监听器管理并规避线程安全、内存泄漏等陷阱。

Java 中要让一个自定义集合具备变量变动监听能力,核心不是“监控内存地址”或“轮询检测”,而是把状态变更行为显式收口——所有修改操作必须经过可控入口(如 add、set、remove 等方法),并在这些入口中主动触发通知。观察者模式在这里起的是“解耦通知逻辑”作用:集合不关心谁来响应变化,只负责广播;监听者也不依赖集合内部实现,只响应事件。
定义清晰的监听契约
先设计一个轻量、语义明确的回调接口,聚焦集合行为本身:
- 用 CollectionEvent 封装关键信息:操作类型(ADD/REMOVE/SET/CLEAR)、被影响的元素、索引(若适用)、旧值(如 set 时)
- 避免泛型擦除问题:接口可带泛型参数
CollectionListener<e></e>,让监听器明确知道处理的是什么类型的数据 - 不强制要求监听器抛异常或阻塞主线程,保持调用轻量
在集合操作中嵌入通知点
以 ObservableArrayList<e></e> 为例,继承 ArrayList 并重写关键 mutator 方法:
-
add(E e)→ 调用super.add(e)后,发onAdded(e, size()-1) -
set(int index, E e)→ 先取旧值get(index),再super.set(...),最后发onSet(index, oldValue, e) -
remove(Object o)和remove(int index)同理:先记录影响,再执行,再通知 -
clear()可批量通知,或发一个onCleared()事件,避免逐个触发开销
支持多监听器与生命周期管理
集合内部维护 List<collectionlistener>></collectionlistener>,提供标准注册/注销方法:
-
addListener(CollectionListener<e> listener)</e>:检查非空,去重添加(可用IdentityHashMap避免 equals 误判) -
removeListener(CollectionListener<e> listener)</e>:安全移除,不报错 - 可选支持优先级或条件过滤(例如只监听字符串长度 >5 的元素),通过包装监听器或增加注册参数实现
避免常见陷阱
实际使用中容易忽略但影响稳定性的问题:
-
线程安全:若集合会被多线程修改,通知逻辑需同步(如用
synchronized(listeners)迭代),或改用CopyOnWriteArrayList存储监听器 -
内存泄漏:监听器持有 Activity 或 Fragment 引用时,务必在 onDestroy/onDestroyView 中调用
removeListener - 递归通知:监听器内部又调用同一集合的修改方法,可能引发栈溢出。可在通知前设标志位临时屏蔽,或文档明确禁止在回调中修改源集合
-
不替代属性监听:该方案监听的是集合结构变化(增删改),不是集合内对象的字段变化。如需监听
list.get(0).name改变,需在对应对象上另加观察者










