我有一行需要解析,如下所示:
@UNIT,a,b,c,,,,d,e,,,
我希望 Java 将以下值存储在列表中:
[0] => a
[1] => b
[2] => c
[3] => null
[4] => null
[5] => null
[6] => d
[7] => e
[8] => null
[9] => null
[10] => null
我想用逗号分隔值并用 null
替换空值.
我用以下代码归档了大部分内容:
metaObject.unit = Arrays.stream(line
.split(","))
.skip(line.startsWith("@UNIT,") ? 1 : 0)
.map(String::trim)
.map(s -> " ".equals(s) || "".equals(s) || "_".equals(s)? null : s)
.collect(Collectors.toList());
在哪里metaObject.unit
定义为 List<String> unit = new ArrayList<String>();
问题是 Java 会忽略最后一个非空元素之后出现的空元素。我在给定情况下得到的输出是:
[0] => a
[1] => b
[2] => c
[3] => null
[4] => null
[5] => null
[6] => d
[7] => e
我不明白为什么Java不像以前那样威胁空元素。有什么技巧可以解决这个问题吗?
最佳答案
问题其实出在line.split(",")
。
默认情况下,引用 split(regex)
的 Javadoc :
Trailing empty strings are therefore not included in the resulting array.
所以这个调用的结果是[@UNIT, a, b, c, , , , d, e]
。
您想要的是包括尾随的空字符串,因此您需要调用 line.split(",", -1)
(注意第二个负参数)。引用 split(regex, limit)
的 Javadoc ,关于limit
参数:
If n is non-positive then the pattern will be applied as many times as possible and the array can have any length.
更正后的代码:
metaObject.unit = Arrays.stream(line
.split(",", -1))
.skip(line.startsWith("@UNIT,") ? 1 : 0)
.map(String::trim)
.map(s -> s.isEmpty() || "_".equals(s) ? null : s)
.collect(Collectors.toList());
(请注意,我删除了对 "".equals(s)
的调用,因为如果是这样的话,之前对 trim
的调用会使该 String 成为空字符串,正如 Holger 在他的评论中指出的那样,我将 "".equals(s)
替换为更简洁的 s.isEmpty()
).
关于java - Java 中的 Lambda 函数会跳过元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32995834/