我们的代码包含复杂的Comparators,用于在整个应用程序中对

java对象进行排序.从历史上看,这些都有效,但自从

Java 7中引入TimSort以来,我们偶尔会发现比较方法违反了它的一般合同!错误..取决于对象中保存的数据.

这是我们的一个传统比较器的例子(可能差不多十年之久 – 原谅狡猾):

public int compare(TemplateBean b1, TemplateBean b2) {

// avoid null pointer exceptions

if (b1 == null && b2 == null) return 0;

if (b1 == null) return 1;

if (b2 == null) return -1;

int cmp = 0;

if ("UNATTACHED".equals(b1.getStatusCode()) &&

!"UNATTACHED".equals(b2.getStatusCode())) {

cmp = 1;

}

if (!"UNATTACHED".equals(b1.getStatusCode()) &&

"UNATTACHED".equals(b2.getStatusCode())) {

cmp = -1;

}

if (!"UNATTACHED".equals(b1.getStatusCode()) &&

!"UNATTACHED".equals(b2.getStatusCode()) &&

!"FIELDSIMPLE".equals(b1.getRefRltshpTypeCode()) &&

!"FIELDSIMPLE".equals(b2.getRefRltshpTypeCode()) &&

!"CUSTOM".equals(b1.getRefRltshpTypeCode()) &&

!"CUSTOM".equals(b2.getRefRltshpTypeCode()) &&

!"FUNCTION".equals(b1.getRefRltshpTypeCode()) &&

!"FUNCTION".equals(b2.getRefRltshpTypeCode())) {

String parent1 = b1.getGroupCode() == null ? "" : b1.getGroupCode().toUpperCase();

String parent2 = b2.getGroupCode() == null ? "" : b2.getGroupCode().toUpperCase();

cmp = parent1.compareTo(parent2);

}

if (cmp == 0) {

Integer i1 = b1.getSortOrder() == null ? Const.ZERO : b1.getSortOrder();

Integer i2 = b2.getSortOrder() == null ? Const.ZERO : b2.getSortOrder();

cmp = i1.compareTo(i2);

}

if (cmp == 0) {

String s1 = b1.getShortDescription();

if (s1 == null) s1 = "";

String s2 = b2.getShortDescription();

if (s2 == null) s2 = "";

cmp = s1.compareToIgnoreCase(s2);

}

return cmp; }

所以,我想复制这个功能,但是使用一个可以安全地与TimSort一起使用的Comparator.

从代码中你可以看到这个比较有多个级别..

>它将比较组代码.

>如果组代码相同,它将比较排序顺序.

>如果排序顺序相同,则会比较说明.

这意味着它将在特定级别返回比较结果.这可能是两个字符串或两个整数的比较结果.我认为这就是打破TimSort的原因.

我能够让这个Comparator解决一般合同问题的唯一方法是对bean的内容进行散列并执行字符串比较.其他想法包括编写我们自己的排序功能..当然有更好的方法吗?

是否应该以另一种方式构建bean来支持它?

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐