存储现场作业以供以后完成

发布于 2024-11-14 08:33:14 字数 1819 浏览 2 评论 0原文

我有两节课。第一个类有 someField,第二个类需要更改它,因此第一个类调用 FirstClass.setSomeField(value)。第二个类此时无法更改该字段,因此它将这个 FutureChange 存储到一个列表中,稍后它将遍历该列表并应用必要的更改。该类必须以可以比较 FutureChange 实例的方式存储它,即避免两次设置相同的字段,以及其他事情。

实施 FutureChange 的最佳方式是什么?通过反思,这很容易。问题是我将有数百个类,每个类都有许多字段。

我什至尝试了一个带有字段名称开关的地图:

public class Example { 

    public static Integer number;
    public static String words;

    public static void main(String args[]) {
        Map<Field, Object> map = new HashMap<Field, Object>();
            // store modifications
        map.put(Field.number, new Integer(10));
        map.put(Field.words, "Words");
        // some time later
        for(Map.Entry<Field, Object> entry: map.entrySet()) {
            modify(entry.getKey(), entry.getValue());
        }
    }

    public static void modify(Field m, Object value) {
        switch(m){
        case number:
            number = (Integer) value;
            break;
        case words:
            words = (String) value;
            break;
        }
    }

    public enum Field {
        number,
        words;
    }
}

但这不是最有效的方法,并且随着类变大,可能会堵塞。有人知道如何最好地实施这个吗?

更多代码:

public class Main {
    FirstClass a = new FirstClass();
    SecondClass b = new SecondClass();
    // Third, Fourth, etc.

    public static void main(String args[]) {
        while(true) {
            // run each, no modifications allowed
            a.run(); // may want to modify several variables of b
            b.run(); // same as above
            // end of all runs, now modify
            a.modifyAll();
            b.modifyAll();
        }
    }
}

如您所见,我必须在运行期间存储它,并稍后执行。

存储匿名内部 Callable 并稍后调用将是完美的,但我需要检查它在做什么,以便我可以比较两个并确定它们是否冲突。

I have two classes. The first class has someField which the second class needs to change, so the first class calls FirstClass.setSomeField(value). The second class can not change the field at that moment, so it stores this FutureChange into a list which it will go through at a later time and apply the necessary changes. The class must store it in a way that it can compare instances of FutureChange, i.e. to avoid setting the same field twice, and other things.

What is the best way to implement FutureChange? With reflection, this is easy. The problem is that I will have hundreds of classes, each class with many fields.

I even tried a map, with a switch for field names:

public class Example { 

    public static Integer number;
    public static String words;

    public static void main(String args[]) {
        Map<Field, Object> map = new HashMap<Field, Object>();
            // store modifications
        map.put(Field.number, new Integer(10));
        map.put(Field.words, "Words");
        // some time later
        for(Map.Entry<Field, Object> entry: map.entrySet()) {
            modify(entry.getKey(), entry.getValue());
        }
    }

    public static void modify(Field m, Object value) {
        switch(m){
        case number:
            number = (Integer) value;
            break;
        case words:
            words = (String) value;
            break;
        }
    }

    public enum Field {
        number,
        words;
    }
}

But this isn't the most effective way, and could get clogged up as the classes get larger. Anyone know how to best implement this?

Some more code:

public class Main {
    FirstClass a = new FirstClass();
    SecondClass b = new SecondClass();
    // Third, Fourth, etc.

    public static void main(String args[]) {
        while(true) {
            // run each, no modifications allowed
            a.run(); // may want to modify several variables of b
            b.run(); // same as above
            // end of all runs, now modify
            a.modifyAll();
            b.modifyAll();
        }
    }
}

As you can see, I must store it during the runs, and execute later.

Storing anonymous inner Callable and calling later would be perfect, but I need to examine what it is doing so that I can compare two and determine whether they are conflicting.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吃→可爱长大的 2024-11-21 08:33:14

我会按照你的建议使用反射。这比直接应用更改要慢得多。如果您确实想要提高效率,那么最好将代码分为两个阶段,一个阶段使用当前值,另一个阶段应用更改,而不是尝试存储更改。

public class StoredChanges {
    private final Map<Object, Map<String, Object>> changes = new IdentityHashMap<Object, Map<String, Object>>();

    public void storeChange(Object o, String fieldName, Object value) {
        Map<String, Object> changedForObject = changes.get(o);
        if (changedForObject == null)
            changes.put(o, changedForObject = new LinkedHashMap<String, Object>());
        changedForObject.put(fieldName, value);
    }

    public void applyChanges() {
        for (Map.Entry<Object, Map<String, Object>> objectMapEntry : changes.entrySet()) {
            Object o = objectMapEntry.getKey();
            for (Map.Entry<String, Object> fieldChange : objectMapEntry.getValue().entrySet()) {
                String fieldName = fieldChange.getKey();
                try {
                    Method setter = o.getClass().getMethod("set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1));
                    setter.invoke(o, fieldChange.getValue());
                } catch (Exception e) {
                    e.printStackTrace(); // or log it.
                }
            }
        }
        changes.clear();
    }
}

I would use reflections as you suggested. This is going to be much slower than applying the changes directly. If you really want efficiency, you are better off breaking your code into two phases/stages one which uses the current value and one which applies the changes rather than trying to store the changes.

public class StoredChanges {
    private final Map<Object, Map<String, Object>> changes = new IdentityHashMap<Object, Map<String, Object>>();

    public void storeChange(Object o, String fieldName, Object value) {
        Map<String, Object> changedForObject = changes.get(o);
        if (changedForObject == null)
            changes.put(o, changedForObject = new LinkedHashMap<String, Object>());
        changedForObject.put(fieldName, value);
    }

    public void applyChanges() {
        for (Map.Entry<Object, Map<String, Object>> objectMapEntry : changes.entrySet()) {
            Object o = objectMapEntry.getKey();
            for (Map.Entry<String, Object> fieldChange : objectMapEntry.getValue().entrySet()) {
                String fieldName = fieldChange.getKey();
                try {
                    Method setter = o.getClass().getMethod("set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1));
                    setter.invoke(o, fieldChange.getValue());
                } catch (Exception e) {
                    e.printStackTrace(); // or log it.
                }
            }
        }
        changes.clear();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文