Java中的Lambda函数跳过元素

Java中的Lambda函数跳过元素,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,我有一行需要解析,如下所示: @单位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

我有一行需要解析,如下所示:

@单位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 unit=new ArrayList()

问题是Java忽略了最后一个非空元素之后出现的空元素。在给定的情况下,我得到的输出是:

[0] => a
[1] => b
[2] => c
[3] => null
[4] => null
[5] => null
[6] => d
[7] => e

我不明白为什么Java不像以前那样威胁空元素。有什么诀窍可以解决这个问题吗?

问题实际上来自
line.split(“,”)

默认情况下,引用以下内容的Javadoc:

因此,结果数组中不包括尾随的空字符串

所以这个调用的结果是
[@UNIT,a,b,c,d,e]

您希望包含尾随的空字符串,因此需要调用
line.split(“,”,-1)
(注意第二个负参数)。引用的Javadoc,关于
limit
参数:

如果n为非正,则图案将被应用尽可能多的次数,并且阵列可以具有任意长度

更正代码:

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
的调用,因为如果是这种情况,前面对
trim
的调用将使该字符串变为空字符串,正如霍尔格在其评论中指出的那样,我将
“”.equals
替换为更干净的
s.isEmpty()

然后可以替换
“”.equals)
使用
s.isEmpty()
这更干净,imho.@Holger,对我来说,更干净的方法是创建一个单独的方法,如
布尔isEmptyEntry(String s){return s.isEmpty()| s.equals(“”| | s.equals(|)}
,这样它就可以被单独支持、测试和重用。顺便说一句,在当前代码中,
s.equals(“”
永远不会像
trim
@Drudge之后发生的那样为真,如果您的IDE具有自动完成功能,则无论何时键入
.spl,第二个参数都应显示在建议的结果中␣。事实上,研究文档是成功的一半;)@塔吉尔·瓦列夫:答案中已经提到,字符串永远不能是
”。我不确定
s.isEmpty()| | s.equals(“|”)
是否超过了阈值,应该单独使用一个可测试的方法。顺便说一句,您也可以编写
s.matches(“\u?”)
来通过一个调用来测试所有内容,但是,这可能会让您觉得需要承担一些开销…