[Android]Collections.unmodifiableList方法的使用与场景

在公司接触到Collections类的unmodifiableList方法
觉得用法挺特殊的,所以学习了下,简单而言,看名字就知道,将参数中的List返回一个不可修改的List.

觉得以下这篇文章写得很好,说 明了它的应用场景。

在《重构——改善既有代码的设计》一书中,有一种重构手法叫Encapsulate Collection
(封装集群),为了演示该重构手法,我写了四个类,通过对比重构前后的代码,加深对
这一重构手法的理解。

类Student有一ArrayList属性,如果没有阅读《重构——改善既有代码的设计》一书,
很多人可能会像我一样,如下设计类Student。但是,如果通过Student.getCourses()
获得对ArrayList属性引用后,就可以任意为Student对象添加“课程”,而Student对象
对此一无所知,这不符合面向对象编程的习惯。

package com.readonlylist;

import Java.util.ArrayList;

public class Student
{
    private String name;

    private ArrayList<String> courses;

    public Student(String name, ArrayList<String> courses)
    {
 this.name = name;
 this.courses = courses;
    }

    public ArrayList<String> getCourses()
    {
        return courses;
    }

    public void setCourses(ArrayList<String> courses)
    {
        this.courses = courses;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }    
}

package com.readonlylist;

import java.util.ArrayList;

public class Test
{
    public static void main(String[] args)
    {
 ArrayList<String> list = new ArrayList<String>();
 list.add("001");
 list.add("002");
        Student s = new Student("Tom", list);

        ArrayList<String> anotherList = s.getCourses();

        anotherList.add("999");

        System.out.println("Tom's course.length = " + s.getCourses().size());
    }
}

重构后的Student类如下所示:

package com.readonlylist;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Student1
{
    private String name;

    private ArrayList<String> courses;

    public Student1(String name, ArrayList<String> courses)
    {
 this.name = name;
 this.courses = courses;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public void addCourse(String course)
    {
 courses.add(course);
    }

    public String removeCourse(String course)
    {
 boolean removed = courses.remove(courses);

 if (removed)
 {
     return course;
 }
 else
 {
            return null;
 }
    }

    public List<String> getCourses()
    {
 return Collections.unmodifiableList(courses);
    }
}

package com.readonlylist;

import java.util.List;
import java.util.ArrayList;

public class Test1
{
    public static void main(String[] args)
    {
 ArrayList<String> list = new ArrayList<String>();
 list.add("001");
 list.add("002");
        Student1 s = new Student1("Tom", list);

        List<String> anotherList = s.getCourses();

        /**
         * throws java.lang.UnsupportedOperationException
         * should replace with s.addCourse(String course)
         */
        anotherList.add("999"); 

        // never reached
        System.out.println("Tom's course.length = " + s.getCourses().size());        
    }
}

重构后,Student1类,仅对外提供的getCourses()方法,而没有setCourses()方法,而且
通过getCourses()方法获得的courses是“只读的”,如果你试图向其添加一个新课程,则
抛出java.lang.UnsupportedOperationException。你必须通过Student1.addCourse()来
向特定的Student1对象添加一个新课程。就好像,你必须让顾客自己向购物车里放食物,
而不能在顾客毫不知情下,偷偷向其购物车里放食物

package com.example.kucun2.entity.data; import android.os.Handler; import android.os.Looper; import android.util.Log; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; public class SynchronizedList<T extends SynchronizableEntity> { private static final String TAG = "AsyncEntityList"; private final List<T> internalList = new CopyOnWriteArrayList<>(); private final List<ListChangeListener<T>> listeners = new ArrayList<>(); private final EntityChangeListener<T> entityChangeListener = new EntityChangeListener<>(); private Class<T> type; // 列表变更监听器接口 public interface ListChangeListener<T> { void onItemAdded(T item, int position); void onItemRemoved(T item, int position); void onSyncStarted(T item); void onSyncSuccess(T item); void onSyncFailure(T item, String error); void onListChanged(); } public Class<T> getType() { return type; } public SynchronizedList(Class<T> type) { this.type=type; } // 操作回调接口 public interface OperationCallback<T> { void onSuccess(T item); void onFailure(T item, String error); } // 注册监听器 public void addListChangeListener(ListChangeListener<T> listener) { listeners.add(listener); } // 移除监听器 public void removeListChangeListener(ListChangeListener<T> listener) { listeners.remove(listener); } // 通知所有监听器 private void notifyListeners(Runnable action) { new Handler(Looper.getMainLooper()).post(() -> { for (ListChangeListener<T> listener : listeners) { action.run(); } }); } // 异步添加元素 public void addAsync(T item, OperationCallback<T> callback) { if (item == null || internalList.contains(item)) return; // 1. 预添加状态(UI可立即显示) int position = internalList.size(); internalList.add(item); registerListener(item); notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onItemAdded(item, position); listener.onSyncStarted(item); } }); // 2. 后台执行同步 new Thread(() -> { item.sync("add", new SynchronizableEntity.SyncCallback() { @Override public void onSyncSuccess(SynchronizableEntity entity) { notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onSyncSuccess((T) entity); listener.onListChanged(); } }); if (callback != null) callback.onSuccess((T) entity); } @Override public void onSyncFailure(String error) { internalList.remove(item); unregisterListener(item); notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onSyncFailure((T) item, error); listener.onItemRemoved((T) item, position); } }); if (callback != null) callback.onFailure((T) item, error); } }); }).start(); } // 异步移除元素 public void removeAsync(T item, OperationCallback<T> callback) { if (!internalList.contains(item)) return; int position = internalList.indexOf(item); internalList.remove(item); unregisterListener(item); notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onItemRemoved(item, position); listener.onSyncStarted(item); } }); new Thread(() -> { item.sync("remove", new SynchronizableEntity.SyncCallback() { @Override public void onSyncSuccess(SynchronizableEntity entity) { notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onSyncSuccess((T) entity); } }); if (callback != null) callback.onSuccess((T) entity); } @Override public void onSyncFailure(String error) { internalList.add(position, item); // 回滚 registerListener(item); notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onSyncFailure((T) item, error); listener.onItemAdded(item, position); } }); if (callback != null) callback.onFailure((T) item, error); } }); }).start(); } // 获取不可修改的列表视图(用于RecyclerView) public List<T> getViewList() { return Collections.unmodifiableList(internalList); } // 实体变更监听器 private static class EntityChangeListener<T extends SynchronizableEntity> implements PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent evt) { ((T) evt.getSource()).sync(null); } } private void registerListener(T element) { if (element != null) { element.addPropertyChangeListener(entityChangeListener); } } private void unregisterListener(T element) { if (element != null) { element.removePropertyChangeListener(entityChangeListener); } } } removePropertyChangeListener?
06-25
package com.example.kucun2.entity.data; import android.os.Handler; import android.os.Looper; import android.util.Log; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 线程安全的异步操作列表 * * @param <T> 列表元素类型,需继承自 SynchronizableEntity * * @apiNote 提供异步添加/移除元素功能,支持UI监听器通知 * @threadSafe 内部使用 CopyOnWriteArrayList 保证线程安全 */ public class SynchronizedList<T extends SynchronizableEntity> { private static final String TAG = "SynchronizedList"; // 使用静态线程池提高效率 private static final ExecutorService ASYNC_EXECUTOR = Executors.newFixedThreadPool(4); // 主线程处理器 private final Handler mainHandler = new Handler(Looper.getMainLooper()); // 内部存储(线程安全) private final List<T> internalList = new CopyOnWriteArrayList<>(); // 列表变更监听器 private final List<ListChangeListener<T>> listeners = new ArrayList<>(); private Class<T> type; /** * 构造方法 * * @param type 列表元素类型(用于反射) */ public SynchronizedList(Class<T> type) { this.type = type; } /** * 获取列表元素类型 * * @return 元素类型Class对象 */ public Class<T> getType() { return type; } //================ 监听器接口 ================// /** * 列表变更监听器接口 * * @param <T> 元素类型 */ public interface ListChangeListener<T> { /** * 元素添加事件 * * @param item 添加的元素 * @param position 添加位置 */ void onItemAdded(T item, int position); /** * 元素移除事件 * * @param item 移除的元素 * @param position 移除位置 */ void onItemRemoved(T item, int position); /** * 同步开始事件 * * @param item 正在同步的元素 */ void onSyncStarted(T item); /** * 同步成功事件 * * @param item 同步成功的元素 */ void onSyncSuccess(T item); /** * 同步失败事件 * * @param item 同步失败的元素 * @param error 错误信息 */ void onSyncFailure(T item, String error); /** * 列表整体变更事件 */ void onListChanged(); } /** * 操作回调接口 * * @param <T> 元素类型 */ public interface OperationCallback<T> { /** * 操作成功回调 * * @param item 操作的元素 */ void onSuccess(T item); /** * 操作失败回调 * * @param item 操作的元素 * @param error 错误信息 */ void onFailure(T item, String error); } //================ 监听器管理 ================// /** * 添加列表变更监听器 * * @param listener 要添加的监听器 */ public void addListChangeListener(ListChangeListener<T> listener) { if (listener != null) { listeners.add(listener); } } /** * 移除列表变更监听器 * * @param listener 要移除的监听器 */ public void removeListChangeListener(ListChangeListener<T> listener) { listeners.remove(listener); } /** * 通知所有监听器(在主线程执行) * * @param action 要执行的通知动作 */ private void notifyListeners(Runnable action) { mainHandler.post(() -> { for (ListChangeListener<T> listener : listeners) { action.run(); } }); } //================ 异步操作 ================// /** * 异步添加元素 * * @param item 要添加的元素 * @param callback 操作结果回调 * * @implNote 1. 立即添加元素到列表(UI可见) * 2. 后台执行同步操作 * 3. 根据同步结果更新状态 */ public void addAsync(T item, OperationCallback<T> callback) { if (item == null || internalList.contains(item)) return; // 1. 预添加状态(UI可立即显示) int position = internalList.size(); internalList.add(item); // 通知UI元素添加和同步开始 notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onItemAdded(item, position); listener.onSyncStarted(item); } }); // 2. 后台执行同步 ASYNC_EXECUTOR.execute(() -> { // 使用"create"操作类型进行同步 item.sync("create", new SynchronizableEntity.SyncCallback() { @Override public void onSyncSuccess(SynchronizableEntity entity) { // 同步成功,通知监听器 notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onSyncSuccess((T) entity); listener.onListChanged(); } }); // 执行成功回调 if (callback != null) callback.onSuccess((T) entity); } @Override public void onSyncFailure(String error) { // 同步失败,回滚列表 internalList.remove(item); // 通知UI元素移除和同步失败 notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onSyncFailure((T) item, error); listener.onItemRemoved((T) item, position); } }); // 执行失败回调 if (callback != null) callback.onFailure((T) item, error); } }); }); } /** * 异步移除元素 * * @param item 要移除的元素 * @param callback 操作结果回调 * * @implNote 1. 立即从列表移除元素(UI可见) * 2. 后台执行同步操作 * 3. 根据同步结果决定是否回滚 */ public void removeAsync(T item, OperationCallback<T> callback) { if (!internalList.contains(item)) return; // 记录位置用于可能的回滚 int position = internalList.indexOf(item); internalList.remove(item); // 通知UI元素移除和同步开始 notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onItemRemoved(item, position); listener.onSyncStarted(item); } }); // 后台执行同步 ASYNC_EXECUTOR.execute(() -> { // 使用"delete"操作类型进行同步 item.sync("delete", new SynchronizableEntity.SyncCallback() { @Override public void onSyncSuccess(SynchronizableEntity entity) { // 同步成功,通知监听器 notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onSyncSuccess((T) entity); } }); // 执行成功回调 if (callback != null) callback.onSuccess((T) entity); } @Override public void onSyncFailure(String error) { // 同步失败,回滚列表 internalList.add(position, item); // 通知UI元素添加回和同步失败 notifyListeners(() -> { for (ListChangeListener<T> listener : listeners) { listener.onSyncFailure((T) item, error); listener.onItemAdded(item, position); } }); // 执行失败回调 if (callback != null) callback.onFailure((T) item, error); } }); }); } //================ 列表访问 ================// /** * 获取不可修改的列表视图 * * @return 不可修改的列表视图 * * @apiNote 用于RecyclerView等UI组件 */ public List<T> getViewList() { return Collections.unmodifiableList(internalList); } /** * 获取列表大小 * * @return 列表元素数量 */ public int size() { return internalList.size(); } /** * 获取指定位置的元素 * * @param index 元素位置 * @return 指定位置的元素 * * @throws IndexOutOfBoundsException 如果索引越界 */ public T get(int index) { return internalList.get(index); } } SynchronizableEntity有id属性 SynchronizedList接受list集合,并合并不会触发同步,根据属性id更新数据
最新发布
06-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值