覆盖 DefaultGroovyMethods 方法

Override DefaultGroovyMethods method

有没有办法轻松覆盖 DefaultGroovyMethods 中的 toSet(Collection<T> self) 方法?
它的实现使用HashMap

public static <T> Set<T> toSet(Collection<T> self) {
    Set<T> answer = new HashSet<T>(self.size());
    answer.addAll(self);
    return answer;
}

但我想使用 LinkedHashMap 来保留参数集合中元素的顺序。

我尝试过元编程(已经在各种自定义中使用过几次类),例如

Collection.metaClass.toSet = {
    println 'in'
    Collection self = (Collection) delegate
    Set<Collection> answer = new LinkedHashSet<Collection>(self.size())
    answer.addAll(self)
    return answer
}

但运气不好(无法进入那个闭包)。
任何建议都将非常受欢迎。谢谢提前!

ps:我目前正在开发 Grails 4.0.3 应用程序,Groovy 2.5.6

您可以使用 Groovy extensions module 覆盖此方法。它在常规 Groovy 代码中工作正常,但在与 Grails 框架一起使用时也应该工作。考虑以下示例:

package com.example

import groovy.transform.CompileStatic

@CompileStatic
class MyDefaultGroovyMethods {

    static <T> Set<T>  toSet(final Collection<T> self) {
        final Set<T> set = new LinkedHashSet<T>(self.size())
        set.addAll(self)
        return set
    }
}

您可以通过创建以下 src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule 文件来注册此辅助方法以覆盖 Collection.toSet() 方法:

moduleName = my-default-groovy-methods-module
moduleVersion = 1.0
extensionClasses = com.example.MyDefaultGroovyMethods

然后你可以用这样的东西来测试它:

def xs = [1,3,2,4]

def set =  xs.toSet()

println xs.toSorted()

println set

println set.class

输出:

[1, 2, 3, 4]
[1, 3, 2, 4]
class java.util.LinkedHashSet