我正在尝试学习 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]。 预先感谢。
您的第一个条件是删除项目,直到找到非空项目为止。第二个条件是删除项目,直到找到空项目为止。添加一个“!”达到您的第一个条件以获得预测结果。
dropWhile 的 Javadoc 指出:
如果此流是有序的,则在删除与给定谓词匹配的元素的最长前缀后,返回由该流的剩余元素组成的流。
在第一个片段中,
Stream
的第一个元素不满足a -> a.isEmpty()
,因此没有元素被删除。
在第二个片段中,
Stream
中的前3个元素满足d -> !d.isEmpty()
,因此这3个元素被删除,留下""
、"e"
和"f"
。
为了更好的理解算法,可以尝试更换一个
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);
}
我花了一些时间,才成功地将我头脑中的错误逻辑转变为正确的逻辑。一开始我得到了与 Harsh Kumrawat 相同的结果。
以下两个答案对我帮助最大:
1号
只要提供的条件为真,“dropWhile”就会运行。当条件为假时,它会停止。在第一个循环中,条件从一开始就是假的。在第二个循环中,流的 2 个元素为真。 – x 银子 2018 年 10 月 2 日 17:52
2号
为了更好地理解算法,可以尝试更换一个Stream版本:
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);
}
亚历山大·皮罗霍夫 2018 年 10 月 2 日 17:50
平安归来