【问题标题】:Struggling with simple Groovy List operations挣扎于简单的 Groovy List 操作
【发布时间】:2015-08-18 14:41:41
【问题描述】:

我在这里抽象了一个非常简单的情况,我想将一个字符串列表传递给我的cleanLines 函数并返回一个字符串列表。不幸的是,我是 Groovy 的新手,我花了大约一天的时间试图让它工作但无济于事。这是一个显示我遇到的问题的独立测试:

import static org.junit.Assert.*;

import java.util.List;

import org.junit.Test;

class ConfigFileTest {

    private def tab = '\t'
    private def returnCarriage = '\r'
    private def equals = '='

    List <String> cleanLines(List <String> lines) {
        lines = lines.collect(){it.findAll(){c -> c != tab && c != returnCarriage}}
        lines = lines.findAll(){it.contains(equals)}
        lines = lines.collect{it.trim()}
    }

    @Test
    public void test() {

        List <String> dirtyLines = ["   Colour=Red",
                                    "Shape=Square   "]

        List <String> cleanedLines = ["Colour=Red",
                                    "Shape=Square"]

        assert cleanLines(dirtyLines) == cleanedLine
    }

}

我相信我遵循了collect()findAll()trim() 的正确用法。但是当我运行测试时,它会在trim() 行中崩溃,说明

groovy.lang.MissingMethodException:没有方法签名: java.util.ArrayList.trim() 适用于参数类型:() 值:[]

。有点可疑。

我已经盯着这个太久了,注意到我的 IDE 认为我在 cleanLines 函数中的第一个 lines 的类型是 List&lt;String&gt;,但是到第二行它的类型是 Collection到第三个它需要类型List&lt;Object&lt;E&gt;&gt;。我认为 String 是一个对象,所以这可能没问题,但它肯定暗示了我的误解。我究竟做错了什么?我怎样才能让我的测试在这里通过?

【问题讨论】:

    标签: list collections groovy


    【解决方案1】:

    这是一个更正的脚本:

    import groovy.transform.Field
    
    @Field
    def tab = '\t'
    @Field
    def returnCarriage = '\r'
    @Field
    def equals = '='
    
    List <String> cleanLines(List <String> lines) {
        lines = lines.findAll { it.contains(equals) }
        lines = lines.collect { it.replaceAll('\\s+', '') }
        lines = lines.collect { it.trim() }
    }
    
    def dirtyLines = ["   Colour=Red",
                                        "Shape=Square   "]
    def cleanedLines = ["Colour=Red", "Shape=Square"]
    
    assert cleanLines(dirtyLines) == cleanedLines
    

    一般findAllcollect 可能不是互斥的,但有不同的用途。使用findAll 查找符合特定条件的元素,而collect 当您需要处理/转换整个列表时。

    【讨论】:

    • 谢谢,这很好。但是,我在cleanLines 中的第一行的目的并不清楚。我想将所有字符串保留在我的数组中,但去掉这些字符串中出现的任何制表符或回车符。我想我真的很想在这里collect 转换元素。有什么想法吗?
    • @Goldstein 我已经更新了我的答案,以使您的意图与cleanLines 函数相匹配。如果不是您要找的,请告诉我。
    • @Goldstein,是的,在这种情况下你需要collect。稍后会更正我的答案。切换顺序也是个好主意,首先查找=,然后使用正则表达式——在这种情况下不是,但通常会更快。
    【解决方案2】:

    这一行

    lines = lines.collect(){it.findAll(){c -> c != tab && c != returnCarriage}}`
    

    用列表列表替换原来的字符串列表。因此 NSME 用于 ArrayList.trim()。您可能希望将 findAll{} 替换为 find{}

    【讨论】:

      【解决方案3】:

      你可以像这样清理这些行:

      def dirtyLines = ["   Colour=Red", "Shape=Square   "]
      def cleanedLines = ["Colour=Red", "Shape=Square"]
      
      assert dirtyLines.collect { it.trim() } == cleanedLines
      

      【讨论】:

        【解决方案4】:

        如果您将cleanLines() 的第一行分成两行并在每行之后打印,您将看到问题。

        it.findAll { c -> c != tab && c != returnCarriage }
        

        将返回符合条件的字符串列表。对lines 列表中的每个字符串调用collect 方法。所以你最终得到了一个字符串列表。我认为您正在寻找的是这样的:

        def cleanLines(lines) {
            return lines.findAll { it.contains(equals) }
                        .collect { it.replaceAll(/\s+/, '') }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-06-21
          • 2023-04-06
          • 2014-08-30
          • 1970-01-01
          • 2017-12-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多