Stream.dropWhile() doesn't return correct value in two different values

瘦欲@ 提交于 2021-02-07 18:38:16

问题


I am trying to learn new features in Java-9 I come to know about the dropWhile method of Stream but it is returning different values in two different scenarios. Here is my code

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);

    }
}

Here is the answer what I am getting

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

What I think in first condition it should print [,World]. Thanks in advance.


回答1:


The dropWhile method, introduced in Java 9, will remove the longest starting set of elements that match the predicate.

Returns, if this stream is ordered, a stream consisting of the remaining elements of this stream after dropping the longest prefix of elements that match the given predicate.

Because your condition is that the item is empty, and the first item is not empty, nothing is removed, leaving ["Hello", "", "World"] intact.

At the end, when you call dropWhile with the opposite condition, is not empty, the first 3 items match and are removed, leaving ["", "e", "f"], which are the remaining items.

This is the expected behavior.




回答2:


Your first condition is saying to drop items until a non-empty item is found The second condition says to drop items until an empty item is found. Add a '!' to your first condition to get your predicted result.




回答3:


The Javadoc of dropWhile states:

Returns, if this stream is ordered, a stream consisting of the remaining elements of this stream after dropping the longest prefix of elements that match the given predicate.

In the first snippet, the first element of the Stream doesn't satisfy a -> a.isEmpty(), so no elements are dropped.

In the second snippet, the first 3 elements in the Stream satisfy d -> !d.isEmpty(), so these 3 elements are dropped, leaving "", "e" & "f".




回答4:


In order to better understand the algorithm, you can try to replace a Stream version:

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

with a classic for loop:

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);
}


来源:https://stackoverflow.com/questions/52613584/stream-dropwhile-doesnt-return-correct-value-in-two-different-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!