GroovyArrayList对字符串感到困惑

4ioopgfo  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(411)

我看到一些混乱的行为,从这个代码。

def fileArrayMeta  = newFile.readLines()
def file3 = fileArrayMeta.collect{ line -> line.split("\\s+") }
println file3[0]
println file3[0].getClass()

此操作的预期结果应该是。

=> [, NOTE, *ENTRY, STATEMENT, *.]
=> class java.util.ArrayList

这个操作的实际结果是。

=> [, NOTE, *ENTRY, STATEMENT, *.]
=> class [Ljava.lang.String;

为什么会这样?

println file3[0].removeAll("", null)

线程“main”groovy.lang.missingmethodexception中出现异常:没有方法的签名:[ljava.lang.string;。removeall()适用于参数类型:(java.lang.string,null)值:[,null]
我想这也应该管用,为什么不呢?

def clean4 = clean3.each{it.collect{ it != "" && it != null }}
    println clean4[0]
ndh0cuux

ndh0cuux1#

你也可以使用 line.split( /\s+/ ) as List

v8wbuo2f

v8wbuo2f2#

string上的split方法返回一个数组,而不是arraylist。您可以改为使用tokenize方法(尽管它不需要regex,这对于在空格上拆分的简单情况来说不是问题),或者在拆分后使用arrays.aslist或 as List .
在groovy中,split和tokenize都有默认值,假定空格作为分隔符,因此regex也不是必需的 line.split() as List 或者 line.tokenize() 够了。制表符和空格都得到处理,重复的工作方式类似:

groovy:000> s = '  a\tb   c d '
===>   a        b   c d
groovy:000> s.tokenize()
===> [a, b, c, d]
groovy:000> s.split() as List
===> [a, b, c, d]

输出 [Ljava.lang.String 是一个符号,告诉你有一个字符串数组。您可以通过对类调用isarray()来检查某个对象是否是数组:

file3[0].class.isArray()

missingmethodexception表示您正在对数组调用removeall。您可以检查对象上可用的方法:

groovy:000> a = s.split()
===> [a, b, c, d]
groovy:000> a.class.isArray()
===> true
groovy:000> a.class.methods
===> [public final void java.lang.Object.wait(long,int) throws java.lang.Interru
ptedException, public final native void java.lang.Object.wait(long) throws java.
lang.InterruptedException, public final void java.lang.Object.wait() throws java
.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Obj
ect), public java.lang.String java.lang.Object.toString(), public native int jav
a.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.g
etClass(), public final native void java.lang.Object.notify(), public final nati
ve void java.lang.Object.notifyAll()]
groovy:000> a.class.methods*.toString().grep {it.contains('removeAll')}
===> []

你希望最后一个例子能做什么?因为调用collect将返回布尔值列表:

groovy> stuff=['asdf', 'zxcv', 'qwerty', '', 'zzz'] 
groovy> stuff.collect { it != '' && it != null } 

Result: [true, true, true, false, true]

collect方法生成调用它的集合的转换副本。但每个都不返回修改后的集合,而是返回原始的未修改集合,下面是一个示例:

groovy> def mylist = ['asdf', 'zxcv', 'qwerty'] 
groovy> def foo = mylist.each {it.toUpperCase()} 
groovy> foo 

Result: [asdf, zxcv, qwerty]

在这里,each中的闭包对mylist或foo的内容没有影响,这与使用collect或 mylist*.toUpperCase() ,它返回通过对mylist的每个元素执行闭包而创建的条目集合。
看起来你对collect的作用感到困惑,你试图用它来过滤(这不起作用)。下面是一个从字符串列表中删除空字符串的示例:

groovy> def mylist = [['a', 'b', ''], ['', 'c', 'd'], ['e', '', 'f']] 
groovy> println mylist.collect {it.findAll()} 

[[a, b], [c, d], [e, f]]

这个 it 调用findall的是一个字符串列表。

相关问题