2

以 Jzombie 模型为例,如果我想查询所有能量等于 5 的人并将他们放在一个列表中,我将有以下代码:

List<Human> human_list = ArrayList<Human>();
Query<Object> query = new PropertyEquals<Object>(context, "energy", 5);
for (Object o : query.query()) {
    Human h = (Human)o;
    human_list.add(h);
}

但是,human_list 中的 human 的顺序是随机的,并且在不同的模拟运行之间是不同的。这会导致结果不一致的问题,如下所示:

run-1:
[human_2, human_4, human_3, human_5, human_1] 

run-2:
[human_1, human_3, human_4, human_2, human_1] 

run-3:
[human_5, human_1, human_3, human_5, human_2] 

我实际上想用 engergy == 5 查询人类并按他们的 id 对它们进行排序,例如:

[human_1, human_2, human_3, human_4, human_5]

这样当我执行一些进一步的操作时,我总能得到一致的结果。

4

1 回答 1

3

不能保证查询的对象顺序,但是假设模型是完全确定的,则对象总是相同的。因此,您需要使用 Collections.sort() 对查询结果列表进行排序。对数组进行排序要求可以比较包含的对象以确定排序。对于包含简单类型(如数字或字符串)的数组,只需在数组上调用 Collections.sort() 即可。由于您想比较代理,您需要让代理类实现可比较的,例如:

public class Human implements Comparable<Human>{

然后提供 compareTo() 方法的实现,如下所示,它根据它们的字符串名称比较代理:

@Override public int compareTo(Human other) { return this.name.compareTo(other.name); }

简单地通过以下方式对人员列表进行排序:

Collections.sort(human_list);

如果您指定 Human 代理名称,例如 Human-1、Human-2 等,您可能会看到类似于以下内容的输出:

[Human-18, Human-3, Human-7, Human-86, Human-92]

而且您每次都会看到相同的订单。由于在此示例中我们正在比较字符串,因此顺序可能不是我们期望的方式。字符串比较查看破折号后的第一个数字,因此“Human-18”排在“Human-3”之前,因为“1”<“3”在这个字符位置。为了以更合乎逻辑的方式进行排序,我们可以将人工代理与整数 ID 进行比较。新的 compareTo 看起来像:

@Override public int compareTo(Human other) { return this.id - other.id; }

这将打印 Human order 如下:

[Human-3, Human-7, Human-18, Human-86, Human-92]

于 2019-11-27T18:25:47.433 回答