Skip to content

Stream 使用指南

Java 8 中新增了一个 Stream (流)的概念,可以更加方便、高效地处理集合数据。Stream 和传统的集合操作非常不同,它提供了一种基于声明式表达式的编程模型,可以让我们轻松地完成复杂的集合操作。

简单来说,Stream 就是一组支持特定聚合操作的元素序列。Stream 以某种形式存在于各种集合类库中,它可以用来代替传统的 for 循环遍历集合,并且可以对集合中的元素进行过滤、映射、排序等操作,最后将结果聚合成一个值。

Stream 特点

  • 转换:在 Stream 中,可以很方便地将一个集合转换为另一个集合,并且转换过程不会修改原有数据。
  • 过滤:可以根据特定条件过滤集合中的元素。
  • 映射:可以通过某个函数对集合中的元素进行映射,生成新的集合。
  • 排序:可以根据集合中元素的某个属性进行排序。
  • 归约:可以将集合中的所有元素归约成一个值。

Stream 常见操作

  • 创建流(CreateStream)

    java
    //从集合创建流
    Stream<String> stream1 = Arrays.asList("hello", "world", "from", "Java").stream();
      
    //从数组创建流
    Stream<Integer> stream2 = Arrays.stream(new Integer[] { 1, 2, 3, 4, 5 });
    
    //使用Stream.of()创建流
    Stream<Double> stream3 = Stream.of(1.0, 2.0, 3.0, 4.0, 5.0);
      
    //使用Stream.iterate()创建无限流
    Stream<Integer> stream4 = Stream.iterate(1, n -> n + 1);
      
    //使用Stream.generate()创建无限流
    Stream<Long> stream5 = Stream.generate(System::currentTimeMillis);
    
    //过滤偶数并加以输出
    stream2.filter(n -> n % 2 == 0).forEach(System.out::println);
  • 转换(Transformation)

    使用 map() 方法将一个集合中的元素转换为另一个元素,并生成一个新的集合。

    java
    // map() 函数将字符串列表中的每个元素转换成该字符串的长度,生成一个整数列表。
    List<String> list = Arrays.asList("apple", "banana", "orange");
    List<Integer> lengths = list.stream()
              .map(String::length)
              .collect(Collectors.toList());
  • 过滤(Filtering)

    使用 filter() 方法可以根据特定的条件过滤集合中的元素,只保留符合条件的元素。

    java
    // filter() 函数保留了集合中包含字母 "a" 的字符串,生成一个新的字符串列表
    List<String> list = Arrays.asList("apple", "banana", "orange", "peach");
    List<String> filtered = list.stream()
              .filter(str -> str.contains("a"))
              .collect(Collectors.toList());
  • 映射(Mapping)

    使用 flatMap() 方法对集合中的元素进行映射,生成一个新的集合。

    java
    // flatMap() 函数将嵌套的集合拆分成一维数组,并生成一个整数列表
    List<List<Integer>> numbers = Arrays.asList(
            Arrays.asList(1, 2),
            Arrays.asList(3, 4, 5),
            Arrays.asList(6, 7, 8, 9));
    List<Integer> flattened = numbers.stream()
              .flatMap(Collection::stream)
              .collect(Collectors.toList());
  • 排序(Sorting)

    使用 sorted() 方法可以根据集合中元素的某个属性进行排序。

    java
    // sorted() 函数根据字符串的自然顺序对字符串列表中的元素进行排序,并生成一个新的字符串列表
    List<String> list = Arrays.asList("orange", "banana", "apple");
    List<String> sorted = list.stream()
              .sorted()
              .collect(Collectors.toList());
  • 归约(Reduction)

    使用 reduce() 方法可以将集合中的所有元素归约成一个值。

    java
    // reduce() 函数将整数列表中的所有元素求和,生成一个 Optional 类型的结果
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
    Optional<Integer> sum = list.stream()
            .reduce(Integer::sum);

中间操作和收集操作

操作返回值类型操作描述
filter(Predicate<T> predicate)Stream<T>过滤流中不符合条件的元素
map(Function<T, R> mapper)Stream<R>将流中的元素映射为另一个类型
flatMap(Function<T, Stream<R>> mapper)Stream<R>将每个流元素映射为一个流,再将所有流合并成一个流
distinct()Stream<T>去除流中重复的元素
sorted()Stream<T>按升序排序流中的元素
peek(Consumer<T> action)Stream<T>对流中的元素执行操作而不改变流本身
limit(long maxSize)Stream<T>限制最大的元素个数
skip(long n)Stream<T>跳过前 n 个元素
concat(Stream<T> a, Stream<T> b)Stream<T>合并两个流
collect(Collector<T, A, R> collector)R将流中的元素收集到一个容器中,然后返回经过容器转换后的结果
count()long返回流中元素的数量
max(Comparator<T> comparator)Optional<T>根据指定的比较器返回流中的最大元素
min(Comparator<T> comparator)Optional<T>根据指定的比较器返回流中的最小元素
findFirst()Optional<T>返回流中的第一个元素
findAny()Optional<T>返回流中的任意一个元素

Collectors 类的静态工厂方法

方法返回类型描述
toList()Collector<T, ?, List<T>>将流中元素收集到一个List集合中
toSet()Collector<T, ?, Set<T>>将流中元素收集到一个Set集合中
toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper)Collector<T, ?, Map<K,U>>根据指定的键值映射函数将流中元素收集到一个Map集合中,如果有重复的键,则抛出IllegalStateException异常
toConcurrentMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper)Collector<T, ?, ConcurrentMap<K,U>>根据指定的键值映射函数将流中元素收集到一个ConcurrentMap集合中,如果有重复的键,则抛出IllegalStateException异常
joining()Collector<CharSequence, ?, String>将流中元素拼接成一个字符串
joining(CharSequence delimiter)Collector<CharSequence, ?, String>将流中元素以指定的分隔符拼接成一个字符串
joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)Collector<CharSequence, ?, String>将流中元素以指定的分隔符、前缀和后缀拼接成一个字符串
counting()Collector<T, ?, Long>返回流中元素的数量
summingInt(ToIntFunction<? super T> mapper)Collector<T, ?, Integer>将流中元素经过指定函数转换后的结果求和
averagingInt(ToIntFunction<? super T> mapper)Collector<T, ?, Double>将流中元素经过指定函数转换后的结果求平均数
maxBy(Comparator<? super T> comparator)Collector<T, ?, Optional<T>>根据指定的比较器返回流中的最大元素
minBy(Comparator<? super T> comparator)Collector<T, ?, Optional<T>>根据指定的比较器返回流中的最小元素