我有一个用类填充的TreeSet。我希望按照它们的继承顺序排列这些,只是按字母顺序排列(以创建一个常量顺序)。但由于某种原因,如果要添加的类的顺序不正确,则会导致类无法正确排序。
这是我的比较者:
class OrderedComparator implements Comparator<Class<?>> {
@Override
int compare(Class<?> clazz1, Class<?> clazz2) {
if (clazz1 == clazz2) {
return 0
} else if (clazz1.isAssignableFrom(clazz2)) {
return -1
} else if (clazz2.isAssignableFrom(clazz1)) {
return 1
} else {
return clazz1.canonicalName.compareTo(clazz2.canonicalName)
}
}
}
以下是失败测试的示例:
def 'OrderedSet is ordered in inheritence order, classes added multiple times'() {
setup:
Set<Class<?>> orderedSet = new TreeSet<>(new OrderedComparator())
when:
orderedSet.add(com.benjaminsproule.swagger.gradleplugin.test.springmvc.ExtendedTestResourceWithClassAnnotation.class)
orderedSet.add(com.benjaminsproule.swagger.gradleplugin.test.springmvc.TestResourceWithClassAnnotation.class)
orderedSet.add(com.benjaminsproule.swagger.gradleplugin.test.jaxrs.ExtendedTestResourceWithoutClassAnnotation.class)
orderedSet.add(com.benjaminsproule.swagger.gradleplugin.test.jaxrs.TestResourceWithClassAnnotation.class)
orderedSet.add(com.benjaminsproule.swagger.gradleplugin.test.springmvc.TestResourceWithoutClassAnnotation.class)
orderedSet.add(com.benjaminsproule.swagger.gradleplugin.test.jaxrs.ExtendedTestResourceWithClassAnnotation.class)
orderedSet.add(com.benjaminsproule.swagger.gradleplugin.test.jaxrs.TestResourceWithoutClassAnnotation.class)
orderedSet.add(com.benjaminsproule.swagger.gradleplugin.test.springmvc.ExtendedTestResourceWithoutClassAnnotation.class)
orderedSet.add(com.benjaminsproule.swagger.gradleplugin.test.jaxrs.TestResourceWithClassAnnotation.class)
orderedSet.add(com.benjaminsproule.swagger.gradleplugin.test.jaxrs.ExtendedTestResourceWithClassAnnotation.class)
then:
assert orderedSet[0] == com.benjaminsproule.swagger.gradleplugin.test.jaxrs.TestResourceWithClassAnnotation.class
assert orderedSet[1] == com.benjaminsproule.swagger.gradleplugin.test.jaxrs.ExtendedTestResourceWithClassAnnotation.class
assert orderedSet[2] == com.benjaminsproule.swagger.gradleplugin.test.jaxrs.TestResourceWithoutClassAnnotation.class
assert orderedSet[3] == com.benjaminsproule.swagger.gradleplugin.test.jaxrs.ExtendedTestResourceWithoutClassAnnotation.class
assert orderedSet[4] == com.benjaminsproule.swagger.gradleplugin.test.springmvc.TestResourceWithClassAnnotation.class
assert orderedSet[5] == com.benjaminsproule.swagger.gradleplugin.test.springmvc.ExtendedTestResourceWithClassAnnotation.class
assert orderedSet[6] == com.benjaminsproule.swagger.gradleplugin.test.springmvc.TestResourceWithoutClassAnnotation.class
assert orderedSet[7] == com.benjaminsproule.swagger.gradleplugin.test.springmvc.ExtendedTestResourceWithoutClassAnnotation.class
}
orderedSet的实际值:
0 = {Class@1272} "class com.benjaminsproule.swagger.gradleplugin.test.jaxrs.ExtendedTestResourceWithClassAnnotation"
1 = {Class@1474} "class com.benjaminsproule.swagger.gradleplugin.test.jaxrs.TestResourceWithoutClassAnnotation"
2 = {Class@1475} "class com.benjaminsproule.swagger.gradleplugin.test.jaxrs.ExtendedTestResourceWithoutClassAnnotation"
3 = {Class@1271} "class com.benjaminsproule.swagger.gradleplugin.test.jaxrs.TestResourceWithClassAnnotation"
4 = {Class@1480} "class com.benjaminsproule.swagger.gradleplugin.test.springmvc.ExtendedTestResourceWithoutClassAnnotation"
5 = {Class@1286} "class com.benjaminsproule.swagger.gradleplugin.test.springmvc.TestResourceWithClassAnnotation"
6 = {Class@1287} "class com.benjaminsproule.swagger.gradleplugin.test.springmvc.ExtendedTestResourceWithClassAnnotation"
7 = {Class@1476} "class com.benjaminsproule.swagger.gradleplugin.test.springmvc.TestResourceWithoutClassAnnotation"
我的期望更像是:
0 = {Class@1271} "class com.benjaminsproule.swagger.gradleplugin.test.jaxrs.TestResourceWithClassAnnotation"
1 = {Class@1272} "class com.benjaminsproule.swagger.gradleplugin.test.jaxrs.ExtendedTestResourceWithClassAnnotation"
2 = {Class@1474} "class com.benjaminsproule.swagger.gradleplugin.test.jaxrs.TestResourceWithoutClassAnnotation"
3 = {Class@1475} "class com.benjaminsproule.swagger.gradleplugin.test.jaxrs.ExtendedTestResourceWithoutClassAnnotation"
4 = {Class@1286} "class com.benjaminsproule.swagger.gradleplugin.test.springmvc.TestResourceWithClassAnnotation"
5 = {Class@1287} "class com.benjaminsproule.swagger.gradleplugin.test.springmvc.ExtendedTestResourceWithClassAnnotation"
6 = {Class@1476} "class com.benjaminsproule.swagger.gradleplugin.test.springmvc.TestResourceWithoutClassAnnotation"
7 = {Class@1480} "class com.benjaminsproule.swagger.gradleplugin.test.springmvc.ExtendedTestResourceWithoutClassAnnotation"
我在调试时注意到,并非每个项目都相互比较。
答案 0 :(得分:3)
考虑这些课程
class A extends C {}
class B {}
class C {}
此处A
出现在B
之前(两者都不是另一个的子类,因此按字母顺序排列)。
同样B
出现在C
之前。
如果您的Comparator
具有传递性,则意味着A
出现在C
之前。然而,
compare(A.class, C.class) == 1 // Because A is a subclass of C
意味着A
大于&#34;大于&#34; C
。
一旦开始尝试使用无效比较器进行排序,就不会指定行为。
答案 1 :(得分:0)
尝试改变条件:
if (clazz1 == clazz2) {
return 0;
} else if (clazz1.isAssignableFrom(clazz2)) {
return 1; // this changed
} else if (clazz2.isAssignableFrom(clazz1)) {
return -1; // this changed
} else {
return clazz1.getCanonicalName().compareTo(clazz2.getCanonicalName());
}
因为我在Test *和ExtendedTest *类中看到了期望与实际排序之间的反转。