问题
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