List<T>列表通用过滤模块设计

本文深入探讨了如何利用逆波兰式的求值原理,在数据源为List<T>的情况下,实现灵活且高效的过滤功能。通过逆波兰式转换与求值,不仅解决了表达式求值时的性能优化问题,还提供了构建表达式树和动态方法实现的两种解决方案,旨在提高数据筛选效率,特别适用于大型数据集的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求描述


数据列表如List<Customer>
加载到DataGridView后,如果记录比较多可能需要对其进行二次过滤,即客户端过滤
过滤条件做成可由用户设置的,如下图:




在数据源是DataTable时,使用DataView的RowFilter可以轻松按用户的配置拼接出过滤表达式字符串来,
设置RowFilter就可以实现过滤效果,但是当数据源是List<T>这样由EF,Linq
to sql 等框架返回的集合时要实现上面的功能就需要费点力气了。


问题分析:


首先参考上面的截图,用户设置好过滤条件后会形成:" (工号 = 222 And 部门=人力) Or 性别=女" 这样的过滤表达式,可以表示成(Exp1
And Exp2) Or Exp3
这样的形式.针对"工号=222"这样的Exp求值我们会转变成针对Employe实体的EmpId属性是否等于222的判断(Employe.EmpId==222),这个可以通过反射方式来实现,将多个Exp求值的结果通过And或Or连接并运算得出最终结果,True表示这一行(Employe)符合.


不过考虑Exp1 Or Exp2 Or
Exp3  这样的条件,如果第一个Exp1是True的话结果必定是True,这个时候还去计算Exp2,Exp3是完全多余的,如果List集合有几万条记录(当然超过几千行的列表对用户来说是没有多少意义的,一般人不会看那么多行,这个时候应该想想过滤条件设置是否合理)那么针对列表的每个实体的每个属性(字段)使用反射的方式计算一遍Exp将是一个比较大的开销,好在And与Or跟算术操作符(+,-,*,/)有所不同,And运算时只要两个操作数中有一个是False就没必要计算另外一个操作数(这里的是Exp)而Or在一个操作数是True时就可以忽略另一个操作数。不过当所的Exp都是false时针对上面"Exp1
Or Exp2 Or
Exp3"这样的表达式计算每个Exp是不可避免的

到这里我们可以看到该问题的本质就是表达式求值,而操作符只限And与Or两个二元操作符,最后结果是True或False.



设计实现:



首先我们将用户设置的过滤表达式转变成逆波兰式(后缀表达式),接着传入每个要判断的实体,使用后缀表达式求出该实体是否符合过滤条件,
当然我们也可以将后缀表达式构建成Expression树,接着将该Expression编译成动态方法(委托),使用该委托对每个实体做出判断,下面的代码给出了这两种实现,
经过测试发现两种方法速度区别不大。


自己对逆波兰式求值时需要下面的判定表,如果构建Expression树则Expression.AndAlso或Expression.OrElse会自己判断是否对两个操作数都进行计算(参考下面的代码)



代码:


View Code

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Reflection;
namespace FIStudio.WinUI.Core
{
    public class ExpParser
    {
        
        public ExpParser(List<Elem> midfixList)
        {
            this.MidfixList = midfixList;

        }
        public List<Elem> PostfixList { get; private set; }
        public List<Elem> MidfixList { get; private set; }
        private Stack<Elem> CalcStack = new Stack<Elem>();
        private void GuardMidfixListExist()
        {
            if (MidfixList == null || MidfixList.Count <= 0) throw new Exception("中序列表为null或为空!");
        }
        private void EnsurePostfixReady()
        {
            if (PostfixList == null)
            {
                PostfixList = DoParse(MidfixList);
                if (PostfixList == null || PostfixList.Count <= 0) throw new Exception("后序列表为null或为空!");
            }
        }
        /// <summary>
        /// 判断元素是否符合要求
        /// </summary>
        /// <param name="ent"></param>
        /// <returns></returns>
        public bool IsSatisfy(object ent)
        {
            GuardMidfixListExist();
            EnsurePostfixReady();


            CalcStack.Clear();
            foreach (var item in PostfixList)
            {
                if (item is ExpElem)
                {
                    CalcStack.Push(item);
                    continue;
                }
                #region And 运算
                if (item is AndElem)
                {
                    var op1 = CalcStack.Pop() as ExpElem;
                    var op2 = CalcStack.Pop() as ExpElem;

                    //任意一个是false则直接压入false
                    if (op1.Result == false || op2.Result == false)
                    {
                        CalcStack.Push(new ExpElem() { Result = false });
                        continue;
                    }

                    if (!op1.Result.HasValue && !op2.Result.HasValue)
                    {
                        op1.Compare(ent);
                        if (op1.Result.Value == false)
                        {
                            CalcStack.Push(new ExpElem() { Result = false });
                            continue;
                        }
                        op2.Compare(ent);
                        CalcStack.Push(new ExpElem() { Result = op2.Result });
                        continue;
                    }
                    if (!op1.Result.HasValue && op2.Result == true)
                    {
                        op1.Compare(ent);
                        CalcStack.Push(new ExpElem() { Result = op1.Result });
                        continue;
                    }
                    if (op1.Result == true && !op2.Result.HasValue)
                    {
                        op2.Compare(ent);
                        CalcStack.Push(new ExpElem() { Result = op2.Result });
                        continue;

                    }
                    if (op1.Result == true && op2.Result == true)
                    {
                        CalcStack.Push(new ExpElem() { Result = true });
                        continue;
                    }

                }
                #endregion
                #region Or 运算
                if (item is OrElem)
                {
                    var op1 = CalcStack.Pop() as ExpElem;
                    var op2 = CalcStack.Pop() as ExpElem;

                    //任意一个是true则直接压入true
                    if (op1.Result == true || op1.Result == true)
                    {
                        CalcStack.Push(new ExpElem() { Result = true });
                        continue;
                    }

                    if (!op1.Result.HasValue && !op2.Result.HasValue)
                    {
                        op1.Compare(ent);
                        if (!op1.Result == true)
                        {
                            CalcStack.Push(new ExpElem() { Result = true });
                            continue;
                        }
                        op2.Compare(ent);
                        CalcStack.Push(new ExpElem() { Result = op2.Result });
                    }
                    if (!op1.Result.HasValue && op2.Result == false)
                    {
                        op1.Compare(ent);
                        CalcStack.Push(new ExpElem() { Result = op1.Result });
                        continue;
                    }
                    if (op1.Result == false && !op2.Result.HasValue)
                    {
                        op2.Compare(ent);
                        CalcStack.Push(new ExpElem() { Result = op2.Result });

                        continue;
                    }
                    if (op1.Result == false && op2.Result == false)
                    {
                        CalcStack.Push(new ExpElem() { Result = false });
                    }

                }
                #endregion
            }
            return (CalcStack.Pop() as ExpElem).Result.Value;

        }
        /// <summary>
        /// 生成判断函数
        /// </summary>
        /// <returns></returns>
        public  Expression<Func<T,bool>> GenIsSatisfyFunc<T>()
        {
            GuardMidfixListExist();
            EnsurePostfixReady();
            Stack<object> stack = new Stack<object>();

            ParameterExpression entExp = Expression.Parameter(typeof(T), "ent");
            foreach (var elem in PostfixList)
            {

                if (elem is ExpElem)
                {
                    stack.Push(elem);
                    continue;
                }
                if (elem is AndElem)
                {
                    var elem1 = stack.Pop();
                    var elem2 = stack.Pop();

                    var exp= Expression.AndAlso(GetCallExpression(elem1,entExp),GetCallExpression(elem2,entExp));
                    
                    stack.Push(exp);
                    continue;
                }
                if(elem is OrElem)
                {
                    var elem1 = stack.Pop();
                    var elem2 = stack.Pop();

                    var exp= Expression.OrElse(GetCallExpression(elem1,entExp),GetCallExpression(elem2,entExp));
                    
                    stack.Push(exp);
                    continue;
                }
            }
            LambdaExpression lambda= Expression.Lambda<Func<T,bool>>( stack.Pop() as Expression,entExp);

            return lambda as  Expression<Func<T,bool>>;

        }
        private Expression GetCallExpression(object elem, ParameterExpression entExp)
        {
            if (elem is ExpElem)
            {
               return Expression.Call(Expression.Constant(elem), typeof(ExpElem).GetMethod("Compare"), entExp);
            }
            return elem as Expression;
        }
        /// <summary>
        /// 中序表达式转后缀表达式
        /// </summary>
        /// <param name="midfix"></param>
        /// <returns></returns>
        private  List<Elem> DoParse(List<Elem> midfix)
        {
            Stack<Elem> stack = new Stack<Elem>();
            var list=new List<Elem>();
            foreach (var elem in midfix)
            {
                if (elem is ExpElem)
                {
                    list.Add(elem);
                    continue;
                }
                if (elem is LBElem)
                {
                    stack.Push(elem);
                    continue;
                }
                if (elem is RBElem)
                {
                    var e = stack.Pop();
                    while (!(e is LBElem))
                    {
                        list.Add(e);
                        e = stack.Pop();
                      

                    }
                    continue;
                }
                if((elem is AndElem) || (elem is OrElem))
                {
                    if (stack.Count > 0)
                    {
                        var e = stack.Peek();
                        while ( !(e is LBElem) && elem.Priority <= e.Priority)
                        {
                            list.Add(stack.Pop());
                            if (stack.Count <= 0) break;
                            e = stack.Peek();
                        }
                    }
                    stack.Push(elem);
                }

            }
            while (stack.Count > 0)
            {
                list.Add(stack.Pop());
            }

            return list;

        }
    }
    #region 节点定义
    public class Elem
    {
        public virtual string Name { get; set; }
        public virtual int Priority { get; set; }
        public Object Data { get; set; }
    }
    /// <summary>
    /// 左括号
    /// 注意stack中只会压入'(','And','Or'
    /// </summary>
    public class LBElem : Elem
    {
        public override string Name
        {
            get
            {
                return "(";
            }
        }
        public override int Priority
        {
            get
            {
                return 59;
            }
        }
    }
    /// <summary>
    /// 右括号
    /// </summary>
    public class RBElem : Elem
    {
        public override string Name
        {
            get
            {
                return ")";
            }
        }
        public override int Priority
        {
            get
            {
                return 99;
            }
        }

    }

    public class AndElem : Elem
    {
        public override string Name
        {
            get
            {
                return "And";
            }
        }
        public override int Priority
        {
            get
            {
                return 88;
            }
        }
    }

    public class OrElem : Elem
    {
        public override string Name
        {
            get
            {
                return "Or";
            }
        }
        public override int Priority
        {
            get
            {
                return 77;
            }
        }
    }
    public class ExpElem : Elem
    {

        public override int Priority
        {
            get
            {
                return 66;
            }
        }
        public bool Compare(object ent)
        {
            Console.WriteLine("计算了:" + Name);
            bool? ret=null;
            if (AssertType == Core.CompareType.Equal)
            {
                ret= string.Compare(GetV(ent),Value,true)==0;
            }
            if (AssertType == Core.CompareType.NotEqual)
            {
                ret =  string.Compare(GetV(ent), Value, true) != 0;
            }
            if (AssertType == Core.CompareType.Greate)
            {
                ret = string.Compare(GetV(ent), Value, true) > 0;
            }
            if (AssertType == Core.CompareType.GreateOrEqual)
            {
                ret = string.Compare(GetV(ent), Value, true) >= 0;
            }
            if (AssertType == Core.CompareType.Less)
            {
                ret = string.Compare(GetV(ent), Value, true) < 0;
            }
            if (AssertType == Core.CompareType.LessOrEqual)
            {
                ret = string.Compare(GetV(ent), Value, true) <= 0;
            }
            if (AssertType == Core.CompareType.Contains)
            {
                ret = GetV(ent).Contains(Value);
            }
            if (AssertType == Core.CompareType.NoContains)
            {
                ret =! GetV(ent).Contains(Value);
            }
            if (AssertType == Core.CompareType.StartWith)
            {
                ret = GetV(ent).StartsWith(Value);
            }
            if (AssertType == Core.CompareType.EndWith)
            {
                ret = GetV(ent).EndsWith(Value);
            }
            if (!ret.HasValue) throw new Exception("未知的CompareType!");
            Result = ret;
            return ret.Value;

           
        }
        public bool? Result { get; set; }
        public PropertyInfo Property { get; set; }
        public CompareType AssertType { get; set; }
        public string Value { get; set; }

        private string GetV(object ent)
        {
            var tmp= Property.GetValue(ent, null);
            if (tmp == null) tmp = string.Empty;
            return tmp.ToString();
        }

        
    }

    public enum CompareType { Equal, NotEqual, Less, LessOrEqual, Greate, GreateOrEqual, Contains, NoContains, StartWith, EndWith };

#endregion

}

复制代码

参考:


  逆波兰式构建方法

  1、从左至右扫描一中缀表达式。
               
2、若读取的是操作数,则判断该操作数的类型,并将该操作数存入操作数堆栈
               
3、若读取的是运算符
                   (1)
该运算符为左括号"(",则直接存入运算符堆栈。
                   (2)
该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止,此时抛弃该左括号。
                   (3)
该运算符为非括号运算符:
                       (a)
若运算符堆栈栈顶的运算符为左括号,则直接存入运算符堆栈。
                       (b)
若比运算符堆栈栈顶的运算符优先级高,则直接存入运算符堆栈。
                       (c)
若比运算符堆栈栈顶的运算符优先级低或相等,则输出栈顶运算符到操作数堆栈,
                           
直至运算符栈栈顶运算符低于(不包括等于)该运算符优先级,或为左括号,并将当前运算符压入运算符堆栈。
               
4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。


   逆波兰表达式求值算法:

               1、循环扫描语法单元的项目。
              
2、如果扫描的项目是操作数,则将其压入操作数堆栈,并扫描下一个项目。
              
3、如果扫描的项目是一个二元运算符,则对栈的顶上两个操作数执行该运算。
              
4、如果扫描的项目是一个一元运算符,则对栈的最顶上操作数执行该运算。
              
5、将运算结果重新压入堆栈。
               6、重复步骤2-5,堆栈中即为结果值。


  资源

字符串公式解析器——使用“逆波兰式算法”及C#实现

转载于:https://www.cnblogs.com/lhj588/archive/2012/10/02/2710242.html

package com.example.kucun2.entity.data; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.util.Log; import com.example.kucun2.entity.*; import com.example.kucun2.function.MyAppFnction; import com.example.kucun2.function.SafeLogger; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.*; import java.util.stream.Collectors; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class Data { // 数据集合声明(保持原有属性名不变) public static SynchronizedList<Bancai> bancais = new SynchronizedList<>(Bancai.class); public static SynchronizedList<Caizhi> caizhis = new SynchronizedList<>(Caizhi.class); public static SynchronizedList<Mupi> mupis = new SynchronizedList<>(Mupi.class); public static SynchronizedList<Chanpin> chanpins = new SynchronizedList<>(Chanpin.class); public static SynchronizedList<Chanpin_Zujian> chanpin_zujians = new SynchronizedList<>(Chanpin_Zujian.class); public static SynchronizedList<Dingdan> dingdans = new SynchronizedList<>(Dingdan.class); public static SynchronizedList<Dingdan_Chanpin> dingdan_chanpins = new SynchronizedList<>(Dingdan_Chanpin.class); public static SynchronizedList<Dingdan_chanpin_zujian> Dingdan_chanpin_zujians = new SynchronizedList<>(Dingdan_chanpin_zujian.class); public static SynchronizedList<Kucun> kucuns = new SynchronizedList<>(Kucun.class); public static SynchronizedList<Zujian> zujians = new SynchronizedList<>(Zujian.class); public static SynchronizedList<User> users = new SynchronizedList<>(User.class); public static SynchronizedList<Jinhuo> jinhuos = new SynchronizedList<>(Jinhuo.class); public static final Map<Class, SynchronizedList<SynchronizableEntity>> dataCollectionMap = new HashMap<>(); private static final Gson gson = GsonFactory.createWithIdSerialization(); private static OkHttpClient client; private static final String TAG = "DataLoader"; static { // 静态初始化块:在类加载时执行,保证所有静态字段已初始化 try { Field[] fields = Data.class.getDeclaredFields(); for (Field field : fields) { if (SynchronizedList.class.equals(field.getType())) { SynchronizedList<?> list = (SynchronizedList<?>) field.get(null); if (list != null) { dataCollectionMap.put(list.getEntityType(), (SynchronizedList<SynchronizableEntity>) list); } } } } catch (IllegalAccessException e) { throw new RuntimeException("初始化dataCollectionMap失败", e); } } public static void loadAllData(Context context, LoadDataCallback callback) { ensurePreservedObjects(); if (Looper.myLooper() != Looper.getMainLooper()) { throw new IllegalStateException("Data.loadAllData must be called on main thread"); } if (client == null) { client = MyAppFnction.getClient(); } SynchronizableEntity.setSyncEnabled(false); String url = MyAppFnction.getStringResource("string", "url") + MyAppFnction.getStringResource("string", "url_all"); Request request = new Request.Builder() .url(url) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e(TAG, "Failed to load data", e); SynchronizableEntity.setSyncEnabled(true); safeCallback(callback, false); } @Override public void onResponse(Call call, Response response) throws IOException { if (!response.isSuccessful()) { Log.e(TAG, "Unexpected response code: " + response.code()); safeCallback(callback, false); return; } String responseData = response.body().string(); SynchronizableEntity.setSyncEnabled(true); ensurePreservedObjects(); parseAndAssignData(responseData, context, callback); } }); } // 解析并赋值数据(全面空值处理) private static void parseAndAssignData(String jsonData, Context context, LoadDataCallback callback) { Type informationType = new TypeToken<Information<AllDataResponse>>() {}.getType(); Information<AllDataResponse> information = null; try { information = gson.fromJson(jsonData, informationType); } catch (Exception e) { Log.e(TAG, "JSON解析失败: " + e.getMessage()); safeCallback(callback, false); return; } if (information == null || information.getData() == null || information.getStatus() != 200) { Log.e(TAG, "无效响应数据"); safeCallback(callback, false); return; } AllDataResponse allData = information.getData(); SafeLogger.d("data", "原始数据: " + gson.toJson(allData)); // 安全初始化所有列表(处理空列表) safeInitializeList(allData.bancais); safeInitializeList(allData.caizhis); safeInitializeList(allData.mupis); safeInitializeList(allData.chanpins); safeInitializeList(allData.chanpin_zujians); safeInitializeList(allData.dingdans); safeInitializeList(allData.dingdan_chanpins); safeInitializeList(allData.Dingdan_chanpin_zujians); safeInitializeList(allData.kucuns); safeInitializeList(allData.zujians); safeInitializeList(allData.users); safeInitializeList(allData.jinhuos); // 过滤掉所有列表中的空值 allData.bancais = filterNulls(allData.bancais); allData.caizhis = filterNulls(allData.caizhis); allData.mupis = filterNulls(allData.mupis); allData.chanpins = filterNulls(allData.chanpins); allData.chanpin_zujians = filterNulls(allData.chanpin_zujians); allData.dingdans = filterNulls(allData.dingdans); allData.dingdan_chanpins = filterNulls(allData.dingdan_chanpins); allData.Dingdan_chanpin_zujians = filterNulls(allData.Dingdan_chanpin_zujians); allData.kucuns = filterNulls(allData.kucuns); allData.zujians = filterNulls(allData.zujians); allData.users = filterNulls(allData.users); allData.jinhuos = filterNulls(allData.jinhuos); // 更新列表(保留预置对象) updateList(bancais, allData.bancais); updateList(caizhis, allData.caizhis); updateList(mupis, allData.mupis); updateList(chanpins, allData.chanpins); updateList(chanpin_zujians, allData.chanpin_zujians); updateList(dingdans, allData.dingdans); updateList(dingdan_chanpins, allData.dingdan_chanpins); updateList(Dingdan_chanpin_zujians, allData.Dingdan_chanpin_zujians); updateList(kucuns, allData.kucuns); updateList(zujians, allData.zujians); updateList(users, allData.users); updateList(jinhuos, allData.jinhuos); SynchronizableEntity.setSyncEnabled(false); // 自动关联实体(全面空值防护) automaticAssociation(); // 设置所有实体状态 setAllEntitiesState(SynchronizableEntity.SyncState.MODIFIED); ensurePreservedObjects(); SynchronizableEntity.setSyncEnabled(true); safeCallback(callback, true); } // 安全回调方法 public static void safeCallback(LoadDataCallback callback, boolean success) { new Handler(Looper.getMainLooper()).post(() -> { if (callback != null) { if (success) { callback.onSuccess(); } else { callback.onFailure(); } } }); } // 更新列表内容但保持对象引用不变(空值防护) private static <T extends SynchronizableEntity> void updateList(List<T> existingList, List<T> newList) { if (newList == null) return; // 创建临时列表保留预置对象 List<T> preservedObjects = new ArrayList<>(); for (T item : existingList) { if (item != null && item.isPreservedObject()) { preservedObjects.add(item); } } // 清除原有列表并添加保留对象 existingList.clear(); existingList.addAll(preservedObjects); // 添加新数据,跳过空值和无效ID for (T newItem : newList) { if (newItem != null && newItem.getId() != null && newItem.getId() != -1) { existingList.add(newItem); } } } // 添加确保预置对象存在的方法(空值防护) private static void ensurePreservedObjects() { if (!containsPreservedObject(bancais)) bancais.add(createInstance(Bancai.class)); if (!containsPreservedObject(caizhis)) caizhis.add(createInstance(Caizhi.class)); if (!containsPreservedObject(mupis)) mupis.add(createInstance(Mupi.class)); if (!containsPreservedObject(chanpins)) chanpins.add(createInstance(Chanpin.class)); if (!containsPreservedObject(chanpin_zujians)) chanpin_zujians.add(createInstance(Chanpin_Zujian.class)); if (!containsPreservedObject(dingdans)) dingdans.add(createInstance(Dingdan.class)); if (!containsPreservedObject(kucuns)) kucuns.add(createInstance(Kucun.class)); if (!containsPreservedObject(zujians)) zujians.add(createInstance(Zujian.class)); if (!containsPreservedObject(Dingdan_chanpin_zujians)) Dingdan_chanpin_zujians.add(createInstance(Dingdan_chanpin_zujian.class)); if (!containsPreservedObject(dingdan_chanpins)) dingdan_chanpins.add(createInstance(Dingdan_Chanpin.class)); if (!containsPreservedObject(jinhuos)) jinhuos.add(createInstance(Jinhuo.class)); if (!containsPreservedObject(users)) users.add(createInstance(User.class)); automaticAssociation(); } // 检查列表是否包含预置对象 private static <T extends SynchronizableEntity> boolean containsPreservedObject(List<T> list) { for (T item : list) { if (item != null && item.isPreservedObject()) { return true; } } return false; } // 自动关联实体(全面空值防护) private static void automaticAssociation() { try { for (Class t : dataCollectionMap.keySet()) { setDefaultAssociation(Objects.requireNonNull(dataCollectionMap.get(t))); } } catch (IllegalAccessException | ClassNotFoundException e) { Log.e(TAG, "自动关联失败", e); } } /** * 自动关联实体(加强空值处理) */ private static <T extends SynchronizableEntity> void setDefaultAssociation(SynchronizedList<T> list) throws IllegalAccessException, ClassNotFoundException { for (T t : list) { if (t == null) continue; // 跳过空对象 Class clazz = t.getClass(); Field[] fields = clazz.getDeclaredFields(); for (Field f : fields) { f.setAccessible(true); Class fieldType = f.getType(); // 处理实体引用字段 if (SynchronizableEntity.class.isAssignableFrom(fieldType)) { SynchronizableEntity currentValue = (SynchronizableEntity) f.get(t); // 处理空值或无效ID if (t.getId() < 0 || currentValue == null || currentValue.getId() == null) { // 设置为对应类型的预置对象 SynchronizedList<SynchronizableEntity> targetList = dataCollectionMap.get(fieldType); if (targetList != null && !targetList.isEmpty()) { f.set(t, targetList.stream() .filter(item -> item.isPreservedObject()) .findFirst() .orElse(null)); } } else { // 查找匹配的实体 SynchronizedList<SynchronizableEntity> targetList = dataCollectionMap.get(fieldType); if (targetList != null) { SynchronizableEntity found = targetList.stream() .filter(item -> currentValue.getId().equals(item.getId())) .findFirst() .orElse(null); // 如果找不到,使用预置对象作为回退 f.set(t, found != null ? found : targetList.stream() .filter(SynchronizableEntity::isPreservedObject) .findFirst() .orElse(null)); } } } // 处理列表字段 else if (List.class.isAssignableFrom(fieldType)) { Type genericType = f.getGenericType(); if (genericType instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) genericType; Type[] types = pt.getActualTypeArguments(); if (types.length > 0) { Class itemType = Class.forName(types[0].getTypeName()); if (SynchronizableEntity.class.isAssignableFrom(itemType)) { List<SynchronizableEntity> currentList = (List<SynchronizableEntity>) f.get(t); if (currentList == null) { currentList = new ArrayList<>(); f.set(t, currentList); } // 过滤掉空值 currentList.removeAll(Collections.singleton(null)); // 处理空列表或无效ID if (currentList.isEmpty() || t.getId() < 0) { SynchronizedList<SynchronizableEntity> sourceList = dataCollectionMap.get(itemType); if (sourceList != null && !sourceList.isEmpty()) { currentList.add(sourceList.stream() .filter(SynchronizableEntity::isPreservedObject) .findFirst() .orElse(null)); } } else { // 更新列表中的引用 SynchronizedList<SynchronizableEntity> sourceList = dataCollectionMap.get(itemType); if (sourceList != null) { for (int i = 0; i < currentList.size(); i++) { SynchronizableEntity item = currentList.get(i); if (item == null) continue; SynchronizableEntity found = sourceList.stream() .filter(e -> e.getId().equals(item.getId())) .findFirst() .orElse(null); // 如果找不到,使用预置对象作为回退 currentList.set(i, found != null ? found : sourceList.stream() .filter(SynchronizableEntity::isPreservedObject) .findFirst() .orElse(null)); } } } } } } } // 处理基本类型字段 else { Object value = f.get(t); if (value == null) { // 设置类型安全的默认值 if (String.class.equals(fieldType)) { f.set(t, "无"); } else if (Integer.class.equals(fieldType) || int.class.equals(fieldType)) { f.set(t, -1); } else if (Double.class.equals(fieldType) || double.class.equals(fieldType)) { f.set(t, -1.0); } else if (Boolean.class.equals(fieldType) || boolean.class.equals(fieldType)) { f.set(t, false); } else if (Date.class.equals(fieldType)) { f.set(t, new Date()); } } } } } } /** * 根据传入的Class对象创建对应类型的实例(加强空值防护) */ public static <T> T createInstance(Class<T> clazz) { try { T instance = clazz.getDeclaredConstructor().newInstance(); // 设置默认值 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); Class<?> type = field.getType(); if (type == String.class) { field.set(instance, "无"); } else if (type == Integer.class || type == int.class) { field.set(instance, -1); } else if (type == Double.class || type == double.class) { field.set(instance, -1.0); } else if (type == Boolean.class || type == boolean.class) { field.set(instance, false); } else if (type == Date.class) { field.set(instance, new Date()); } else if (SynchronizableEntity.class.isAssignableFrom(type)) { // 设置为对应类型的预置对象 SynchronizedList<SynchronizableEntity> targetList = dataCollectionMap.get(type); if (targetList != null && !targetList.isEmpty()) { field.set(instance, targetList.stream() .filter(SynchronizableEntity::isPreservedObject) .findFirst() .orElse(null)); } } else if (List.class.isAssignableFrom(type)) { // 初始化为空列表 field.set(instance, new ArrayList<>()); } } // 设置特殊字段 clazz.getMethod("setId", Integer.class).invoke(instance, -1); clazz.getMethod("setState", SynchronizableEntity.SyncState.class) .invoke(instance, SynchronizableEntity.SyncState.PRESERVED); return instance; } catch (Exception e) { Log.e("Data", "创建实例失败: " + clazz.getName(), e); return createSafeFallback(clazz); } } // 安全回退创建 private static <T> T createSafeFallback(Class<T> clazz) { try { return clazz.getDeclaredConstructor().newInstance(); } catch (Exception ex) { throw new RuntimeException("创建回退实例失败", ex); } } // 辅助方法:确保列表不为null private static <T> void safeInitializeList(List<T> list) { if (list == null) { list = new ArrayList<>(); } } // 辅助方法:过滤列表中的空值 private static <T> List<T> filterNulls(List<T> list) { if (list == null) return new ArrayList<>(); return list.stream() .filter(Objects::nonNull) .collect(Collectors.toList()); } // 回调接口 public interface LoadDataCallback { void onSuccess(); void onFailure(); } // 内部类用于解析JSON响应 public static class AllDataResponse { public List<Bancai> bancais; public List<Caizhi> caizhis; public List<Mupi> mupis; public List<Chanpin> chanpins; public List<Chanpin_Zujian> chanpin_zujians; public List<Dingdan> dingdans; public List<Dingdan_Chanpin> dingdan_chanpins; public List<Dingdan_chanpin_zujian> Dingdan_chanpin_zujians; public List<Kucun> kucuns; public List<Zujian> zujians; public List<User> users; public List<Jinhuo> jinhuos; } // 新增方法:设置所有实体状态 private static void setAllEntitiesState(SynchronizableEntity.SyncState state) { setListState(bancais, state); setListState(caizhis, state); setListState(mupis, state); setListState(Dingdan_chanpin_zujians, state); setListState(dingdans, state); setListState(chanpins, state); setListState(chanpin_zujians, state); setListState(zujians, state); setListState(jinhuos, state); setListState(kucuns, state); setListState(users, state); } private static <T extends SynchronizableEntity> void setListState(List<T> list, SynchronizableEntity.SyncState state) { for (T entity : list) { if (entity != null) { entity.setState(state); } } } }结构简化加入详细注释
06-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值