ksc*_*t90 4 java arrays string groovy file
我看到这段代码有些令人困惑的行为.
def fileArrayMeta = newFile.readLines()
def file3 = fileArrayMeta.collect{ line -> line.split("\\s+") }
println file3[0]
println file3[0].getClass()
Run Code Online (Sandbox Code Playgroud)
这个操作的预期结果应该是.
=> [, NOTE, *ENTRY, STATEMENT, *.]
=> class java.util.ArrayList
Run Code Online (Sandbox Code Playgroud)
这个操作的实际结果是.
=> [, NOTE, *ENTRY, STATEMENT, *.]
=> class [Ljava.lang.String;
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
println file3[0].removeAll("", null)
Run Code Online (Sandbox Code Playgroud)
线程"main"中的异常groovy.lang.MissingMethodException:没有方法签名:[Ljava.lang.String; .removeAll()适用于参数类型:(java.lang.String,null)values:[,null]
我认为这也应该有效,为什么不呢?
def clean4 = clean3.each{it.collect{ it != "" && it != null }}
println clean4[0]
Run Code Online (Sandbox Code Playgroud)
java.lang.String上的split方法返回一个数组,而不是ArrayList.您可以使用方法tokenize(虽然它不需要正则表达式对于在空白上拆分的简单情况不是问题),或者在拆分后使用Arrays.asList或将数组转换为列表as List.
在Groovy中,split和tokenize都有默认值,假设空格为分隔符,因此正则表达式不是必需的,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]
Run Code Online (Sandbox Code Playgroud)
输出[Ljava.lang.String是一个表示你有一个字符串数组的符号.您可以通过在类上调用isArray()来检查某些内容是否为数组:
file3[0].class.isArray()
Run Code Online (Sandbox Code Playgroud)
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')}
===> []
Run Code Online (Sandbox Code Playgroud)
你期望最后一个例子做什么?因为对collect的调用将返回一个布尔列表:
groovy> stuff=['asdf', 'zxcv', 'qwerty', '', 'zzz']
groovy> stuff.collect { it != '' && it != null }
Result: [true, true, true, false, true]
Run Code Online (Sandbox Code Playgroud)
collect方法生成一个被调用的集合的转换副本.但每个都没有返回修改后的集合,它返回原始未修改的集合,这是一个例子:
groovy> def mylist = ['asdf', 'zxcv', 'qwerty']
groovy> def foo = mylist.each {it.toUpperCase()}
groovy> foo
Result: [asdf, zxcv, qwerty]
Run Code Online (Sandbox Code Playgroud)
这里的闭包对mylist或foo的内容没有影响,不像你使用collect或者mylist*.toUpperCase(),它返回通过在mylist的每个元素上执行闭包而创建的条目集合.
看起来你对收集的内容感到困惑,而你正试图用它来过滤(这不起作用).这是从字符串列表列表中删除空字符串的示例:
groovy> def mylist = [['a', 'b', ''], ['', 'c', 'd'], ['e', '', 'f']]
groovy> println mylist.collect {it.findAll()}
[[a, b], [c, d], [e, f]]
Run Code Online (Sandbox Code Playgroud)
该it说的findAll被称为上是一个字符串列表.