跳转至

Java Streams 全面解析

简介

Java Streams 是 Java 8 引入的一个强大的新特性,它为处理集合数据提供了一种声明式的方式。通过使用 Streams,开发者可以更简洁、更高效地对集合进行过滤、映射、排序等操作,而无需编写繁琐的循环代码。本文将详细介绍 Java Streams 的基础概念、使用方法、常见实践以及最佳实践,帮助读者深入理解并高效使用这一特性。

目录

  1. 基础概念
    • 什么是 Java Streams
    • Stream 与 Collection 的区别
  2. 使用方法
    • 创建 Stream
    • 中间操作
    • 终端操作
  3. 常见实践
    • 过滤元素
    • 映射元素
    • 排序元素
    • 聚合操作
  4. 最佳实践
    • 避免重复使用 Stream
    • 并行流的使用
    • 延迟执行的利用
  5. 小结
  6. 参考资料

基础概念

什么是 Java Streams

Java Streams 是一个来自数据源的元素队列并支持聚合操作。这里的数据源可以是集合、数组、I/O 通道等。Stream 提供了一种高效且易于使用的方式来处理数据,它允许你以声明式的方式处理集合中的元素。

Stream 与 Collection 的区别

  • 数据处理方式:Collection 主要用于存储和访问数据,而 Stream 则侧重于对数据的计算。
  • 数据遍历:Collection 中的元素需要手动进行遍历,而 Stream 提供了自动遍历的功能。
  • 延迟执行:Stream 是延迟执行的,只有在调用终端操作时才会真正执行中间操作。

使用方法

创建 Stream

Java 提供了多种创建 Stream 的方式,以下是一些常见的示例:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamCreationExample {
    public static void main(String[] args) {
        // 从集合创建 Stream
        List<String> list = Arrays.asList("apple", "banana", "cherry");
        Stream<String> streamFromList = list.stream();

        // 从数组创建 Stream
        String[] array = {"apple", "banana", "cherry"};
        Stream<String> streamFromArray = Arrays.stream(array);

        // 创建空 Stream
        Stream<String> emptyStream = Stream.empty();

        // 创建无限 Stream
        Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 1);
    }
}

中间操作

中间操作是指在 Stream 上进行的一系列操作,这些操作不会立即执行,而是返回一个新的 Stream。常见的中间操作包括 filtermapsorted 等。

import java.util.Arrays;
import java.util.List;

public class IntermediateOperationsExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // 过滤操作
        List<Integer> evenNumbers = numbers.stream()
                .filter(n -> n % 2 == 0)
                .toList();

        // 映射操作
        List<Integer> squaredNumbers = numbers.stream()
                .map(n -> n * n)
                .toList();

        // 排序操作
        List<Integer> sortedNumbers = numbers.stream()
                .sorted()
                .toList();
    }
}

终端操作

终端操作是指在 Stream 上进行的最后一个操作,它会触发中间操作的执行,并返回一个结果。常见的终端操作包括 forEachcollectreduce 等。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class TerminalOperationsExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // forEach 操作
        numbers.stream()
                .forEach(System.out::println);

        // collect 操作
        List<Integer> squaredNumbers = numbers.stream()
                .map(n -> n * n)
                .collect(Collectors.toList());

        // reduce 操作
        int sum = numbers.stream()
                .reduce(0, Integer::sum);
    }
}

常见实践

过滤元素

过滤操作是指根据指定的条件筛选出符合条件的元素。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FilteringExample {
    public static void main(String[] args) {
        List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");

        // 过滤出长度大于 5 的水果
        List<String> longFruits = fruits.stream()
                .filter(fruit -> fruit.length() > 5)
                .collect(Collectors.toList());
    }
}

映射元素

映射操作是指将 Stream 中的每个元素转换为另一个元素。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class MappingExample {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("hello", "world");

        // 将每个单词转换为大写
        List<String> upperCaseWords = words.stream()
                .map(String::toUpperCase)
                .collect(Collectors.toList());
    }
}

排序元素

排序操作是指对 Stream 中的元素进行排序。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class SortingExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(5, 3, 1, 4, 2);

        // 对数字进行升序排序
        List<Integer> sortedNumbers = numbers.stream()
                .sorted()
                .collect(Collectors.toList());
    }
}

聚合操作

聚合操作是指将 Stream 中的元素合并为一个结果。

import java.util.Arrays;
import java.util.List;

public class AggregationExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // 计算数字的总和
        int sum = numbers.stream()
                .reduce(0, Integer::sum);

        // 计算数字的最大值
        int max = numbers.stream()
                .reduce(Integer.MIN_VALUE, Integer::max);
    }
}

最佳实践

避免重复使用 Stream

Stream 是一次性使用的,一旦调用了终端操作,就不能再使用该 Stream 进行其他操作。因此,在需要多次使用 Stream 时,应该创建新的 Stream。

import java.util.Arrays;
import java.util.List;

public class AvoidReusingStreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // 第一次使用 Stream
        long count = numbers.stream().count();

        // 第二次使用 Stream,需要重新创建
        int sum = numbers.stream().reduce(0, Integer::sum);
    }
}

并行流的使用

并行流可以利用多核处理器的优势,提高 Stream 操作的性能。但是,并行流也会带来一定的开销,因此在使用并行流时需要谨慎。

import java.util.Arrays;
import java.util.List;

public class ParallelStreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // 使用并行流计算总和
        int sum = numbers.parallelStream().reduce(0, Integer::sum);
    }
}

延迟执行的利用

Stream 的中间操作是延迟执行的,只有在调用终端操作时才会真正执行。因此,可以利用这一特性,在中间操作中进行多次转换,而不会立即消耗资源。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class LazyEvaluationExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // 中间操作不会立即执行
        var stream = numbers.stream()
                .filter(n -> n % 2 == 0)
                .map(n -> n * n);

        // 调用终端操作,触发中间操作的执行
        List<Integer> result = stream.collect(Collectors.toList());
    }
}

小结

Java Streams 是 Java 8 引入的一个强大的新特性,它为处理集合数据提供了一种声明式的方式。通过使用 Streams,开发者可以更简洁、更高效地对集合进行过滤、映射、排序等操作。本文介绍了 Java Streams 的基础概念、使用方法、常见实践以及最佳实践,希望能帮助读者深入理解并高效使用这一特性。

参考资料