Stream.dropWhile()在两个不同的值中未返回正确的值

时间:2018-10-02 17:39:05

标签: java java-stream java-9

我正在尝试学习Java-9的新功能,我了解了Stream的dropWhile方法,但是它在两种不同的情况下返回了不同的值。 这是我的代码

package src.module;

import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.List;

public class Test {

    public static void main(String[] args) {

        String s[] = new String[3];
        s[0] = "Hello";
        s[1] = "";
        s[2] = "World";
        List<String> value = Stream.of(s).dropWhile(a -> a.isEmpty()).collect(Collectors.toList());

        System.out.println(value);

        List<String> values = Stream.of("a", "b", "c", "", "e", "f").dropWhile(d -> !d.isEmpty())
                .collect(Collectors.toList());
        System.out.println(values);

    }
}

这是我得到的答案

[Hello, , World]
[, e, f]

我认为在第一个条件下应该打印[,World]。 预先感谢。

4 个答案:

答案 0 :(得分:3)

Java 9中引入的dropWhile method将删除与谓词匹配的最长起始元素集。

  

如果此流是有序的,则在删除与给定谓词匹配的元素的最长前缀之后,返回由该流的其余元素组成的流。

因为您的条件是该项目为空,而第一个项目不为空,则什么也没有删除,使["Hello", "", "World"]完好无损。

最后,当您以相反的条件调用dropWhile时不为空,则前3个项目匹配并被删除,剩下的["", "e", "f"]则为剩余项目。

这是预期的行为。

答案 1 :(得分:3)

您的第一个条件是说要丢弃物品,直到找到一个非空物品。第二个条件是说要丢弃物品,直到找到一个空物品。添加一个“!”达到您的第一个条件以获得预期的结果。

答案 2 :(得分:2)

dropWhile的Javadoc指出:

  

如果此流是有序的,则在删除与给定谓词匹配的元素的最长前缀之后,返回由该流的其余元素组成的流。

在第一个代码段中,Stream的第一个元素不满足a -> a.isEmpty(),因此不会删除任何元素。

在第二个片段中,Stream中的前3个元素满足d -> !d.isEmpty(),因此将这3个元素删除,剩下"""e"和{{1} }。

答案 3 :(得分:2)

为了更好地理解算法,您可以尝试替换Stream版本:

List<String> value = Stream.of(s).dropWhile(String::isEmpty).collect(Collectors.toList());

具有经典的for循环:

List<String> value = new ArrayList<>();
boolean dropping = true;

for (int i = 0; i < s.length; i++) {
    String str = s[i];
    if (dropping) {
        if (str.isEmpty()) {
            continue;
        }
        dropping = false;
    }
    value.add(str);
}