在对象之间共享信息

时间:2012-06-08 13:27:25

标签: java

在任务中共享TaskKey,哪一个更好?还有其他更好的方法吗?

way1由一个密钥对象共享。这样,客户端代码(Task Queue)更易于编写以配置任务表。但是每个任务都必须浪费内存来存储TaskKey对象。

class TaskKey {
    int key1;
    int key2;
    // key3...
    TaskKey(int key1, int key2) {
        this.key1 = key1;
        this.key2 = key2;
    }
}

abstract class Task implements Cloneable {
    TaskKey key;
    int taskData;
    Task(TaskKey key) {
        this.key = key;
    }
    int getKey1() {
        return key.key1;
    }
    int getKey2() {
        return key.key2;
    }
    Task newInstance(int taskData) {
        Task task = (Task) clone();
        task.taskData = taskData;
        return task;
    }
    abstract void doSomething();
}

class TaskQueue {
    Task[][] taskTable;
    void addTask(Task task) {
        taskTable[task.getKey1()][task.getKey2()] = task;
    }
    void config() {
        addTask(new Task(new TaskKey(1, 1)) {
            void doSomething() {}
        });
        addTask(new Task(new TaskKey(1, 2)) {
            void doSomething() {}
        });
        addTask(new Task(new TaskKey(2, 1)) {
            void doSomething() {}
        });
    }

    Queue<Task> queue;
    void put(int key1, int key2, int taskData) {
        Task task = taskTable[key1][key2];
        queue.add(task.newInstance(taskData));
    }
}

way2由任务类共享。这样,客户端代码(Task Queue)很难写入配置任务表(覆盖Task的getKey()方法)。但是每个任务都不需要浪费内存来存储TaskKey对象,因为关键信息由具体的Task类共享。

abstract class Task implements Cloneable {
    int taskData;
    abstract int getKey1();
    abstract int getKey2();
    abstract void doSomething();
    Task newInstance(int taskData) {
        Task task = (Task) clone();
        task.taskData = taskData;
        return task;
    }
}

class TaskQueue {
    Task[][] taskTable;
    void addTask(Task task) {
        taskTable[task.getKey1()][task.getKey2()] = task;
    }
    void config() {
        addTask(new Task() {
            int getKey1() { return 1; }
            int getKey2() { return 1; }
            void doSomething() {}
        });
        addTask(new Task() {
            int getKey1() { return 1; }
            int getKey2() { return 2; }
            void doSomething() {}
        });
        addTask(new Task() {
            int getKey1() { return 2; }
            int getKey2() { return 1; }
            void doSomething() {}
        });
    }

    Queue<Task> queue;
    void put(int key1, int key2, int taskData) {
        Task task = taskTable[key1][key2];
        queue.add(task.newInstance(taskData));
    }
}

另一种方式1和方式2

interface TaskExecutor {
    void exec(Task task);
}

class TaskKey {
    int key1;
    int key2;
    int key3;
    TaskExecutor executor;
}

class Task /*another way1*/ {
    TaskKey key;
    int taskData;// in fact it is not only a int

    int getKey1() { // because i need to retrieve key1 from a task
        return key.key1;
    }
    // also get methods for key2 key3

    void exec(){
        key.executor.exec(this);
    }
}

class Task /*another way2*/ {
    public final int key1;
    public final int key2;
    public final int key3;
    private final TaskExecutor executor;
    int taskData;

    void exec(){
        executor.exec(this);
    }
}

1 个答案:

答案 0 :(得分:0)

你可能不想第二种方式。对于像存储两个int这样简单的事情,反射看起来有点矫枉过正。你从中获得的内存性能非常小,jvm必须更加努力地找出你的方法重载。它最终占用了更多的代码空间(你认为java编译器在哪里存储所有这些额外的信息?)以及减慢执行速度。

第一种方法是这样做的一种方式,但如果它只是存储两个int s那么简单,您可能会考虑在Task类中使用两个键而不是有一个单独的钥匙。

abstract class Task implements Cloneable {
    int taskData;
    int key1;
    int key2;
    Task(int key1_, int key2_) {
        this.key1 = key1_;
        this.key2 = key2_;
    }
    int getKey1() {
        return key1;
    }
    int getKey2() {
        return key2;
    }
    Task newInstance(int taskData) {
        Task task = (Task) clone();
    task.taskData = taskData;
        return task;
    }
    abstract void doSomething();
}

但是,考虑到您已经有Task[][]存储所有这些数据,似乎您不需要这样做,除非您需要获取key1和{{的值1}}来自特定的key2对象,您可以直接执行

Task

但是,如果您需要从特定的void addTask(Task task, int i, int j) { taskTable[i][j] = task; } void config() { addTask(new Task(), 1, 1); } 对象获取key1key2的值,则可以使用Task代替{HashMap<TaskKey,Task> 1}}来存储您的数据。那样你就可以

Task[][]

虽然您可能需要使用您最喜欢的IDE生成HashMap<TaskKey,Task> taskTable; void addTask(Task task, int i, int j) { taskTable.put(new TaskKey(i,j), task); } Task getTask(int i, int j){ return taskTable.get(new TaskKey(i,j)); } void config() { addTask(new Task(), 1, 1); } hashCode()方法。这最终会保持内存效率,并且从阵列中获得相同的恒定时间访问。