0

我想在我的域类中实现默认排序顺序,并立即发现它不适用于该getAll方法。没什么大不了的,我只是用list了。问题是域类中的默认排序顺序不允许您指定多个排序字段(如此处所示)。

Foo我的目标是首先按对象的名称对所有对象进行排序Bar,然后按它们自己的名称。

class Foo {
    String name
    String Bar
}

class Bar {
    String name
}

如何在域类中实现这一点,这样我就不必每次调用时都指定一个长/讨厌的比较器.list()

我的尝试之一:

static Comparator getComparator() { 
    def c = { a, b -> 
    def result = a.bar.name.compareTo( b.bar.name ); 
        if ( result == 0 ) {
            result = a.name.compareTo( b.name );
        }
    }
    return c as Comparator
}

然后我可以打电话Foo.list(Foo.getComparator())……如果我能让它工作的话。

更新:

我想我在这里真的很接近,只是在同一个排序闭包中实现两个比较时遇到了麻烦。

Foo.list().sort{ a, b ->
    def result = a.bar.name <=> b.bar.name;
    // Things mess up when I put this if statement in.
    if( result == 0 ) {
        a.name <=> b.name
    }
}

迪斯科!

class Foo { // My domain class
    // ...

    static Comparator getComparator() {
        def c =[
            compare: { a, b ->
                def result = a.bar.name <=> b.bar.name;
                if( result == 0 ) {
                    result = a.name <=> b.name
                }
                return result
            }
        ] as Comparator
    }

    // ...
}

并在我的控制器中像这样实现:

Foo.list().sort( Foo.getComparator() )

PS:

以上工作,但杰夫斯托里在我发现后在他的答案中发布了一些代码,他的代码工作并且比我的好得多,所以使用它:)

4

2 回答 2

4

在您的情况下,实施是否有意义,并且Foo实施Comparable可以按照您的描述进行比较?然后,当您对列表中的对象进行排序时,因为它们是Comparable,它们将正确排序。

但是,如果您实现它没有意义Comparable,则需要指定一个比较器进行排序。

以下是基于您的评论的一些示例代码:

编辑:

class Person implements Comparable<Person> {

   String firstName
   String lastName

   int compareTo(Person other) {
       int lastNameCompare = lastName <=> other.lastName
       return lastNameCompare != 0 ? lastNameCompare : firstName <=> other.firstName
   }

   String toString() {
     "${lastName},${firstName}"
   }
}

def people = [new Person(firstName:"John",lastName:"Smith"), new Person(firstName:"Bill",lastName:"Jones"), new Person(firstName:"Adam",lastName:"Smith")]
println "unsorted = ${people}"
println "sorted = ${people.sort()}" 

这打印:

unsorted = [Smith,John, Jones,Bill, Smith,Adam]
sorted = [Jones,Bill, Smith,Adam, Smith,John]
于 2012-06-26T02:30:30.100 回答
2

为了进一步简化上面的帖子(我会对此发表评论,但我还没有代表),您可以使用 elvis 运算符链接 groovy 比较运算符:

class Person implements Comparable<Person> {

    String firstName
    String lastName

    int compareTo(Person other) {
        return lastName <=> other.lastName ?: firstName <=> other.firstName
    }

    String toString() {
        "${lastName},${firstName}"
    }
}

def people = [new Person(firstName:"John",lastName:"Smith"), new Person(firstName:"Bill",lastName:"Jones"), new     Person(firstName:"Adam",lastName:"Smith")]
println "unsorted = ${people}"
println "sorted = ${people.sort()}"

这将为您提供相同的结果,因为 0 在 groovy 眼中被认为是错误的,这将使其查看链中的下一个条件。

于 2013-09-09T13:58:02.577 回答