繁体   English   中英

Java Stream - filter() 和 dropWhile() 有什么区别

[英]Java Stream - what is the difference between filter() and dropWhile()

使用 Java 9 方法dropWhile()被添加到 Stream API。 当我阅读文档时,我发现它与 Java 8 filter()方法非常相似。

我错过了什么吗? 这些方法有什么区别?

让我们看一下这个例子:

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

这将给出以下 output:

2
3
1
====
1
1

首先,在有序流中dropWhile仅丢弃匹配元素的最长前缀(参见文档)。 此外,您可以看到filter指定了哪些元素需要通过,而dropWhile指定了哪些元素需要删除。

这是一个显示差异的小程序。

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从 stream 中删除与谓词不匹配的所有元素(在这种情况下: n -> n >= 0 ,因此它删除了负数)。

dropWhile删除与谓词匹配的元素(在本例中: n -> n < 0 ),直到找到与谓词不匹配的元素。 从那时起,它让所有元素都通过。

请注意,在此示例中,用于filterdropWhile的谓词彼此相反。

filter - 是一个无状态的中间操作,它总是返回一个 stream 只包含与给定谓词匹配的元素。

返回一个 stream ,其中包含与给定谓词匹配的此 stream 的元素。

dropWhile - 是一个有状态的中间操作,它也需要一个谓词,基本上就像一个有状态的过滤器。 在遇到与谓词不匹配的第一个元素后, dropWhile()停止丢弃 stream 中的元素。

如果此 stream 已排序,则最长前缀是此 stream 的与给定谓词匹配的元素的连续序列。

如果此 stream 是无序的,并且此 stream 的某些(但不是全部)元素与给定谓词匹配,则此操作的行为是不确定的; 可以自由删除匹配元素的任何子集(包括空集)。

要了解dropWhile行为与有序无序stream 之间的区别,让我们考虑以下示例。

这将是一个无序stream 的示例:

Set<Integer> numbers = Set.of(9, 1, 2, 3, 4, 5, 6, 7, 8);

numbers.stream()
    .dropWhile(i -> i < 9)
    .forEach(System.out::print);

例如 Output 可以是912 ,范围从9123456789 (意味着所有元素都可能存在,output 中的顺序将不可预测)。 因为 stream 是来自源的无序元素可能会出现在 stream 中,并且dropWhile()可以在任何执行点关闭,这就是这种情况下“行为不确定”的意思。

现在让我们看一下订购的 stream

List<Integer> numbers = List.of(9, 1, 2, 3, 4, 5, 6, 7, 8);
    
numbers.stream()
    .dropWhile(i -> i < 9)
    .forEach(System.out::print);

Output:

912345678

9开始,stream 中的第一个元素与谓词不匹配,它将永远不会被再次评估, dropWhile()被关闭并且所有元素都将到达终端操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM