在开源项目鲁尔托中。在该项目中有一个单元测试com.rultor.agents.IndexesRequestsTest#retrievesIndexFromSibling
,如下所示:
@Test
public void retrievesIndexFromSibling() throws Exception {
final String first = "first";
final Talks talks = new Talks.InDir();
talks.create("", first);
talks.get(first).modify(
new Directives().xpath("/talk")
.add("wire").add("href").set("#3").up().up()
.add("archive")
.add("log").attr("id", "3").attr("title", "title3")
.attr("index", "1").up()
);
final String second = "second";
talks.create("", second);
talks.get(second).modify(
new Directives().xpath("/talk")
.add("wire").add("href").set("#4").up().up()
.add("archive")
.add("log").attr("id", "4").attr("title", "title4")
.attr("index", "2").up()
);
final String third = "third";
talks.create("", third);
talks.get(third).modify(
new Directives()
.xpath("/talk").add("wire").add("href").set("#5").up().up()
.add("request").attr("id", "a67890")
.add("args").up()
.add("type").set("merge").up()
);
new IndexesRequests().execute(talks);
MatcherAssert.assertThat(
talks.get(third).read(),
XhtmlMatchers.hasXPaths("/talk/request[@index='5']")
);
}
现在看看测试结束时的调用talks.get(third).read()
。
在Windows下,其结果等于
<?xml version="1.0" encoding="UTF-8"?>
<talk later="false" name="third" number="1" public="true">
<wire>
<href>#5</href>
</wire>
<request id="a67890" index="5">
<args/>
<type>merge</type>
</request>
</talk>
在Linux下,talks.get(third).read()
的结果等于
<?xml version="1.0" encoding="UTF-8"?>
<talk later="false" name="third" number="1" public="true">
<wire>
<href>#5</href>
</wire>
<request id="a67890" index="3">
<args/>
<type>merge</type>
</request>
</talk>
区别:在index
下,request
的5
属性是5
,在Linux-3
下.
为什么?
生成索引的类是com.rultor.agents.IndexesRequests
。
public final class IndexesRequests implements SuperAgent {
@Override
public void execute(final Talks talks) throws IOException {
int idx = this.index(talks);
for (final Talk talk : talks.active()) {
idx += 1;
talk.modify(
new Directives()
.xpath("/talk/request")
.attr("index", Integer.toString(idx))
);
}
}
/**
* Calculates maximal index value for a {@link Talks} object.
* @param talks The {@link Talks} object
* @return The maximal index value
* @throws IOException if the content of one {@link Talk} object can't be read
*/
private int index(final Talks talks) throws IOException {
int index = 0;
for (final Talk talk : talks.active()) {
final int idx = this.index(talk);
if (idx > index) {
index = idx;
}
}
return index;
}
/**
* Calculates maximal (existing) index value of a {@link Talk} object.
* @param talk The {@link Talk} object
* @return The maximal index value
* @throws IOException if the content of the {@link Talk} object can't be read
*/
private int index(final Talk talk) throws IOException {
final Iterable<Integer> indexes = Iterables.transform(
talk.read()
.xpath("/talk/archive/log/@index|/talk/request/@index"),
new Function<String, Integer>() {
@Override
public Integer apply(final String input) {
return Integer.parseInt(input);
}
}
);
final int index;
if (indexes.iterator().hasNext()) {
index = Ordering.natural().max(indexes);
} else {
index = 0;
}
return index;
}
}
除了XPath方法中的index
调用之外,除了index
方法中的调用之外,在Windows和Linux下,代码中还有其他地方可能有不同的行为吗?
更新1 (23.01.2015 14:47 MSK):
System.out.println("Index first: " +
new IndexesRequests().index(talks.get(first)));
System.out.println("Index second: " +
new IndexesRequests().index(talks.get(second)));
System.out.println("Index third: " +
new IndexesRequests().index(talks.get(third)));
Linux和Windows的结果都是一样的:
Index first: 1
Index second: 2
Index third: 0
添加这些诊断消息之后,测试在Linux下不会失败。
更新2 (23.01.2015 15:07 MSK):
我添加了打印talks.active()
结果的代码。
final Iterable<Talk> activeTalks = talks.active();
System.out.println("activeTalks (START)");
for (final Talk talk : activeTalks) {
System.out.println("Talk XML: " + talk.read().toString());
}
System.out.println("activeTalks (END)");
Windows:
activeTalks (START)
Talk XML: <?xml version="1.0" encoding="UTF-8"?>
<talk later="false" name="first" number="1" public="true">
<wire>
<href>#3</href>
</wire>
<archive>
<log id="3" index="1" title="title3"/>
</archive>
</talk>
Talk XML: <?xml version="1.0" encoding="UTF-8"?>
<talk later="false" name="second" number="1" public="true">
<wire>
<href>#4</href>
</wire>
<archive>
<log id="4" index="2" title="title4"/>
</archive>
</talk>
Talk XML: <?xml version="1.0" encoding="UTF-8"?>
<talk later="false" name="third" number="1" public="true">
<wire>
<href>#5</href>
</wire>
<request id="a67890">
<args/>
<type>merge</type>
</request>
</talk>
activeTalks (END)
Linux:
activeTalks (START)
Talk XML: <?xml version="1.0" encoding="UTF-8"?>
<talk later="false" name="third" number="1" public="true">
<wire>
<href>#5</href>
</wire>
<request id="a67890">
<args/>
<type>merge</type>
</request>
</talk>
Talk XML: <?xml version="1.0" encoding="UTF-8"?>
<talk later="false" name="second" number="1" public="true">
<wire>
<href>#4</href>
</wire>
<archive>
<log id="4" index="2" title="title4"/>
</archive>
</talk>
Talk XML: <?xml version="1.0" encoding="UTF-8"?>
<talk later="false" name="first" number="1" public="true">
<wire>
<href>#3</href>
</wire>
<archive>
<log id="3" index="1" title="title3"/>
</archive>
</talk>
activeTalks (END)
发布于 2015-01-23 12:50:18
计算@索引的算法取决于talks.active()交付这些元素的顺序。如果这返回一个(例如,HashMap或HashSet )的值,那么它们在这个系统上可以按一个顺序返回,在那个系统上可以按另一个顺序返回。
定义hashCode可能不会产生可靠的订单。
一种可靠的方法是使用Map或Set来维护插入顺序(如LinkedHash*)。
https://stackoverflow.com/questions/28108708
复制相似问题