java - Java 中的 Lambda 函数会跳过元素

标签 java lambda java-8 java-stream

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

@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/

相关文章:

java - 同步表达式中的方法引用

java - @ConditionalOnProperty 用于列表或数组?

java - 非静态变量 this 在创建类的实例时不能从静态上下文中引用

c# - 从 lambda 表达式参数读取和写入模型属性

java-8 在不创建新列表的情况下过滤列表

java - 无法使用 JavaMail POP 获取 Gmail 收件箱

java - 处理程序的 `handleMessage` 返回主线程的线程 ID 而不是工作线程的线程 ID

java - 如何为井字游戏创建简单、中等和困难级别?

Java Lambda : How it works in JVM & is it OOP?

java - 如何根据值直接过滤集合?