Java流-filter()和dropWhile()之间的区别是什么

cczfrluj  于 2022-12-25  发布在  Java
关注(0)|答案(3)|浏览(204)

随着Java 9方法dropWhile()被添加到流API中,当我阅读文档时,我发现它与Java 8 filter()方法非常相似。
我错过了什么吗?这些方法之间有什么区别?

4c8rllxm

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指定哪些元素需要删除。

nkoocmlb

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 不匹配的元素,从那时起,它允许所有元素通过。
注意,在本例中,用于filterdropWhile的 predicate 是彼此的反义词。

6ju8rftf

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,其范围从9123456789(意味着所有元素可能存在,输出中的顺序将是不可预测的)。因为流是无序的,来自源的元素可能出现在流中,并且dropWhile()可以在执行的任何点被关闭,这就是短语"行为是不确定的"在本例中的意思。
现在我们来看一下 * 有序流 *:

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()将被关闭,所有元素都将到达终端操作。

相关问题