随着Java 9方法dropWhile()被添加到流API中,当我阅读文档时,我发现它与Java 8 filter()方法非常相似。我错过了什么吗?这些方法之间有什么区别?
dropWhile()
filter()
4c8rllxm1#
让我们看一下这个例子:
Stream.of(1, 2, 3, 1) .dropWhile(i -> i < 2) .forEach(System.out::println); System.out.println("===="); Stream.of(1, 2, 3, 1) .filter(i -> i < 2) .forEach(System.out::println);
这将给予以下输出:
2 3 1 ==== 1 1
首先,在有序流中,dropWhile只删除匹配元素的最长前缀(参见文档),而且,您可以看到filter指定哪些元素需要传递,而dropWhile指定哪些元素需要删除。
dropWhile
filter
nkoocmlb2#
下面是一个小程序,显示了不同之处。
public class Example { public static void main(String[] args) { List<Integer> numbers = List.of(-1, -3, -4, 2, 5, -6, -7, 8); // Prints: 2, 5, 8 System.out.println(numbers.stream() .filter(n -> n >= 0) .map(Object::toString).collect(Collectors.joining(", "))); // Prints: 2, 5, -6, -7, 8 System.out.println(numbers.stream() .dropWhile(n -> n < 0) .map(Object::toString).collect(Collectors.joining(", "))); } }
filter从流中删除与 predicate 不匹配的所有元素(在本例中:n -> n >= 0,因此它移除负数)。dropWhile删除与 predicate do 匹配的元素(在本例中:n -> n < 0),直到它找到一个与 predicate 不匹配的元素,从那时起,它允许所有元素通过。注意,在本例中,用于filter和dropWhile的 predicate 是彼此的反义词。
n -> n >= 0
n -> n < 0
6ju8rftf3#
filter-是一个*无状态*中间操作,它总是返回一个只包含与给定 predicate 匹配的元素的流。返回一个流,该流由该流中与给定 predicate 匹配的元素组成。dropWhile-是一个*statefull*中间操作,它也需要一个 predicate ,基本上就像一个有状态过滤器。在遇到第一个与 predicate 不匹配的元素后,dropWhile()停止从流中丢弃元素。如果这个流是ordered,那么最长的前缀是这个流中匹配给定 predicate 的元素的连续序列。如果这个流是无序的,并且这个流的一些(但不是全部)元素匹配给定 predicate ,则这个操作的行为是不确定的;可以自由地丢弃匹配元素的任何子集(包括空集)。为了理解带有 * ordered * 和 * unordered * 流的dropWhile在行为上的区别,让我们考虑以下示例。这是一个 * 无序 * 流的示例:
Set<Integer> numbers = Set.of(9, 1, 2, 3, 4, 5, 6, 7, 8); numbers.stream() .dropWhile(i -> i < 9) .forEach(System.out::print);
例如,输出可以是912,其范围从9到123456789(意味着所有元素可能存在,输出中的顺序将是不可预测的)。因为流是无序的,来自源的元素可能出现在流中,并且dropWhile()可以在执行的任何点被关闭,这就是短语"行为是不确定的"在本例中的意思。现在我们来看一下 * 有序流 *:
912
9
123456789
List<Integer> numbers = List.of(9, 1, 2, 3, 4, 5, 6, 7, 8); numbers.stream() .dropWhile(i -> i < 9) .forEach(System.out::print);
912345678
由于9(流中的第一个元素)与 predicate 不匹配,因此它将永远不会被再次求值,dropWhile()将被关闭,所有元素都将到达终端操作。
3条答案
按热度按时间4c8rllxm1#
让我们看一下这个例子:
这将给予以下输出:
首先,在有序流中,
dropWhile
只删除匹配元素的最长前缀(参见文档),而且,您可以看到filter
指定哪些元素需要传递,而dropWhile
指定哪些元素需要删除。nkoocmlb2#
下面是一个小程序,显示了不同之处。
filter
从流中删除与 predicate 不匹配的所有元素(在本例中:n -> n >= 0
,因此它移除负数)。dropWhile
删除与 predicate do 匹配的元素(在本例中:n -> n < 0
),直到它找到一个与 predicate 不匹配的元素,从那时起,它允许所有元素通过。注意,在本例中,用于
filter
和dropWhile
的 predicate 是彼此的反义词。6ju8rftf3#
filter
-是一个*无状态*中间操作,它总是返回一个只包含与给定 predicate 匹配的元素的流。返回一个流,该流由该流中与给定 predicate 匹配的元素组成。
dropWhile
-是一个*statefull*中间操作,它也需要一个 predicate ,基本上就像一个有状态过滤器。在遇到第一个与 predicate 不匹配的元素后,dropWhile()
停止从流中丢弃元素。如果这个流是ordered,那么最长的前缀是这个流中匹配给定 predicate 的元素的连续序列。
如果这个流是无序的,并且这个流的一些(但不是全部)元素匹配给定 predicate ,则这个操作的行为是不确定的;可以自由地丢弃匹配元素的任何子集(包括空集)。
为了理解带有 * ordered * 和 * unordered * 流的
dropWhile
在行为上的区别,让我们考虑以下示例。这是一个 * 无序 * 流的示例:
例如,输出可以是
912
,其范围从9
到123456789
(意味着所有元素可能存在,输出中的顺序将是不可预测的)。因为流是无序的,来自源的元素可能出现在流中,并且dropWhile()
可以在执行的任何点被关闭,这就是短语"行为是不确定的"在本例中的意思。现在我们来看一下 * 有序流 *:
由于
9
(流中的第一个元素)与 predicate 不匹配,因此它将永远不会被再次求值,dropWhile()
将被关闭,所有元素都将到达终端操作。