使用简单的Groovy List操作挣扎

时间:2015-08-18 14:41:42

标签: list collections groovy

我在这里抽象了一个非常简单的情况,我想在其中将一个字符串列表传递给我的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认为lines函数中第一个cleanLines的类型是List<String>,但是第二行它的类型为Collection,第三个类型为List<Object<E>>。我认为String是一个对象,所以这可能没问题,但它肯定暗示了我的误解。我究竟做错了什么?我怎样才能让我的考试通过?

4 个答案:

答案 0 :(得分: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则需要处理/转换整个列表。

答案 1 :(得分:0)

这一行

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

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

答案 2 :(得分:0)

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

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

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

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

答案 3 :(得分:0)

你可以清理这样的行:

def dirtyLines = ["   Colour=Red", "Shape=Square   "]
def cleanedLines = ["Colour=Red", "Shape=Square"]

assert dirtyLines.collect { it.trim() } == cleanedLines