【问题标题】:Realm - Do not update if property equals领域 - 如果属性等于则不更新
【发布时间】:2023-03-29 15:28:02
【问题描述】:

我正在使用适用于 Android 的领域。我有以下代码并且它可以工作,但我想知道这是否是更新对象的最佳方式以及它是否会导致任何性能问题。

目前,如果状态设置为处理中,我不想更新现有对象。

List<WorkOrderObject> woList = new ArrayList<>();
            for (int i = 0; i < openWorkOrders.size(); i++) {
                if (!visnetawrap.isUserLoggedIn) {
                    return;
                }
                WorkOrderObject wo = visnetawrap.gsonClient.fromJson(openWorkOrders.get(i).toString(), WorkOrderObject.class);

                WorkOrderObject currWO = realmThread.where(WorkOrderObject.class).equalTo("id", wo.getOrderRawId()).findFirst();
                if (currWO != null) {
                    if (currWO.getOrderStatus().equals("Processing")) {
                        continue;
                    }
                }

                issueDateTime = AppUtils.formatTimestampToDateTime(wo.getOrderIssueDate());
                issueDateString = issueDateTime.toLocalDateTime().toString("MM/dd/yyyy", Locale.US);
                dueDateTime = AppUtils.formatTimestampToDateTime(wo.getOrderDueDate());
                dueDateString = dueDateTime.toLocalDateTime().toString("MM/dd/yyyy", Locale.US);

                if (!issueDateString.equals("") && !issueDateString.equals("00/00/0000") && issueDateTime.getYear() >= now.getYear() && !dueDateString.equals("") && !dueDateString.equals("00/00/0000") && dueDateTime.getYear() >= now.getYear()) {
                    //Log.d("dueDate", dueDateString);
                    woList.add(wo);
                }
            }
            realmThread.beginTransaction();
            realmThread.copyToRealmOrUpdate(woList);
            realmThread.commitTransaction();

【问题讨论】:

    标签: android realm


    【解决方案1】:

    我认为基本上是一样的。
    由于您担心性能,这里有一些可以改进的方法。

    private static String PROCESSING = "Processing";
    private static String DATE_FORMAT = "MM/dd/yyyy";
    private static String EMPTY_DATE = "00/00/0000";
    
    public void betterMethod() {
        List<WorkOrderObject> woList = new ArrayList<>(openWorkOrders.size());
    
        //I think this code doesnot need to be inside loop.
        if (!visnetawrap.isUserLoggedIn) {
            return;
        }
        for (int i = 0, j = openWorkOrders.size(); i < j; i++) {
            //Since you are using gson there are ways to convert JsonArray to list directly which is a better way than this
            WorkOrderObject wo = visnetawrap.gsonClient.fromJson(openWorkOrders.get(i).toString(), WorkOrderObject.class);
    
            WorkOrderObject currWO = realmThread.where(WorkOrderObject.class).equalTo("id", wo.getOrderRawId()).findFirst();
    
            if (currWO != null && currWO.getOrderStatus().equals(PROCESSING)) { //Its cleanar way
                continue;
            }
    
            issueDateTime = AppUtils.formatTimestampToDateTime(wo.getOrderIssueDate());
            issueDateString = issueDateTime.toLocalDateTime().toString(DATE_FORMAT, Locale.US);
            dueDateTime = AppUtils.formatTimestampToDateTime(wo.getOrderDueDate());
            dueDateString = dueDateTime.toLocalDateTime().toString(DATE_FORMAT, Locale.US);
    
            //I assume you have stripped out code where it needs string
            //You can use TextUtils.isEmpty() or issueDateString.isEmpty() , 
            // issueDateString.equals("") does is creates new String which is empty and compares issueDateString with it while above methods just check the 
            //length of string
            if (!TextUtils.isEmpty(issueDateString) && !issueDateString.equals(EMPTY_DATE) && issueDateTime.getYear() >= now.getYear() && !TextUtils.isEmpty(dueDateString) && !dueDateString.equals(EMPTY_DATE) && dueDateTime.getYear() >= now.getYear()) {
                //Log.d("dueDate", dueDateString);
                woList.add(wo);
            }
        }
        if (!woList.isEmpty()) {
            realmThread.beginTransaction();
            realmThread.copyToRealmOrUpdate(woList);
            realmThread.commitTransaction();
        }
    }
    
    1. For 循环可能非常大,因此像currWO.getOrderStatus().equals("Processing") 这样的条件语句将创建一个新字符串并进行比较。最好在之前初始化字符串,如上传递。
    2. Converting JsonArray to List

    3. 为什么要实例化 new ArrayList&lt;&gt;(openWorkOrders.size()) 之类的数组并使用带有 for (int i = 0, j = openWorkOrders.size(); i &lt; j; i++) {} 之类的列表的 for 循环
      Streamlining Android Apps: Eliminating Code Overhead by Jake Wharton

    【讨论】:

    • openWorkOrders 是一个 JsonArray,我循环遍历它,因为如果我尝试将其转换为列表,有时手机会崩溃,所以我认为循环遍历 jsonarray 并单独添加每个对象在这种情况下会更好?
    • 用户可以随时注销,所以如果 for 正在循环,如果用户注销,它将取消,这就是为什么 if (!visnetawrap.isUserLoggedIn) { return; } 在循环中。
    • 我认为如果这在主线程中运行,我认为用户登录不会同时发生。
    • 没错,我让它在 AsyncTask 中运行。
    • 现在我们可能会进入一个小深区,我知道的相对较少,如果用户登录发生在检查登录之后怎么办?你可能想让这个我不知道的循环像原子或同步?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多