【问题标题】:Override DefaultGroovyMethods method覆盖 DefaultGroovyMethods 方法
【发布时间】:2021-11-11 14:33:21
【问题描述】:

有没有办法从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

【问题讨论】:

    标签: grails groovy overriding default-method


    【解决方案1】:

    您可以使用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
    

    【讨论】:

    • 这比我希望的建议要多...非常感谢您的详细解释!它就像一个魅力
    猜你喜欢
    • 1970-01-01
    • 2018-06-21
    • 1970-01-01
    • 2016-03-06
    • 2018-03-27
    • 2014-05-27
    • 2014-01-04
    • 2010-11-16
    • 2021-05-16
    相关资源
    最近更新 更多