Java 开发者必备:Stream API 的核心用法与实战技巧

开发 后端
Stream API 提供了一种函数式编程风格的操作集合的方法,使代码更简洁、可读性更高。本文将详细介绍 Java Stream API 的基本用法和一些实践技巧。

Java 8 引入了 Stream API,使得我们可以更加简洁、高效地处理集合。Stream API 提供了一种函数式编程风格的操作集合的方法,使代码更简洁、可读性更高。本文将详细介绍 Java Stream API 的基本用法和一些实践技巧。

什么是 Stream API

Stream 是 Java 8 引入的一个新的抽象,它代表一个支持数据处理操作的序列。Stream 以函数式编程的方式处理数据,可以执行过滤、映射、规约等操作。与传统的集合不同,Stream 不存储数据,而是按需计算。

Stream 的创建方式

可以通过多种方式创建 Stream,常见的方法如下:

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

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

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

        // 使用 Stream.of 创建
        Stream<String> streamOf = Stream.of("1", "2", "3");

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

        // 打印流中的元素
        streamFromList.forEach(System.out::println);
        streamFromArray.forEach(System.out::println);
        streamOf.forEach(System.out::println);
        infiniteStream.limit(5).forEach(System.out::println);
    }
}

常见的中间操作

中间操作返回一个新的 Stream,对原有 Stream 进行处理。常见的中间操作有 filter、map、sorted 和 distinct 等。

filter - 过滤元素

filter 方法用于过滤元素:

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

public class StreamFilterExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
        List<Integer> evenNumbers = numbers.stream()
                                           .filter(n -> n % 2 == 0)
                                           .collect(Collectors.toList());
        System.out.println(evenNumbers); // 输出: [2, 4, 6]
    }
}

map - 映射元素

map 方法用于将元素映射为新的元素:

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

public class StreamMapExample {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("hello", "world");
        List<Integer> wordLengths = words.stream()
                                         .map(String::length)
                                         .collect(Collectors.toList());
        System.out.println(wordLengths); // 输出: [5, 5]
    }
}

sorted - 排序元素

sorted 方法用于对元素进行排序:

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

public class StreamSortedExample {
    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());
        System.out.println(sortedNumbers); // 输出: [1, 2, 3, 4, 5]
    }
}

distinct - 去重元素

distinct 方法用于去除重复元素:

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

public class StreamDistinctExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
        List<Integer> distinctNumbers = numbers.stream()
                                               .distinct()
                                               .collect(Collectors.toList());
        System.out.println(distinctNumbers); // 输出: [1, 2, 3, 4, 5]
    }
}

常见的终端操作

终端操作会触发 Stream 的执行,并返回一个结果。常见的终端操作有 forEach、collect、reduce 和 count 等。

forEach - 遍历元素

forEach 方法用于遍历每一个元素:

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

public class StreamForEachExample {
    public static void main(String[] args) {
        List<String> items = Arrays.asList("a", "b", "c");
        items.stream().forEach(System.out::println);
    }
}

collect - 收集元素

collect 方法用于将 Stream 的元素收集到一个集合中:

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

public class StreamCollectExample {
    public static void main(String[] args) {
        List<String> items = Arrays.asList("a", "b", "c");
        List<String> collectedItems = items.stream()
                                           .collect(Collectors.toList());
        System.out.println(collectedItems); // 输出: [a, b, c]
    }
}

reduce - 规约元素

reduce 方法用于将元素组合起来:

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

public class StreamReduceExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        int sum = numbers.stream()
                         .reduce(0, Integer::sum);
        System.out.println(sum); // 输出: 15
    }

count - 统计元素个数

count 方法用于计算元素的个数:

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

public class StreamCountExample {
    public static void main(String[] args) {
        List<String> items = Arrays.asList("a", "b", "c");
        long count = items.stream().count();
        System.out.println(count); // 输出: 3
    }
}

实战技巧

并行流 - 提高性能

并行流可以利用多核处理器的优势,加快流操作的执行速度。可以通过 parallelStream 方法创建并行流:

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);
        System.out.println(sum); // 输出: 15
    }
}

组合多个 Stream

可以使用 flatMap 方法将多个 Stream 组合为一个:

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

public class StreamFlatMapExample {
    public static void main(String[] args) {
        List<List<Integer>> listOfLists = Arrays.asList(
            Arrays.asList(1, 2, 3),
            Arrays.asList(4, 5, 6),
            Arrays.asList(7, 8, 9)
        );
        List<Integer> combinedList = listOfLists.stream()
                                                .flatMap(List::stream)
                                                .collect(Collectors.toList());
        System.out.println(combinedList); // 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]
    }
}

错误处理

在流操作中,可能会出现异常,可以使用 peek 方法进行调试:

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

public class StreamErrorHandlingExample {
    public static void main(String[] args) {
        List<String> items = Arrays.asList("1", "2", "a", "4");
        List<Integer> numbers = items.stream()
                                     .map(item -> {
                                         try {
                                             return Integer.parseInt(item);
                                         } catch (NumberFormatException e) {
                                             System.err.println("Error parsing: " + item);
                                             return null;
                                         }
                                     })
                                     .filter(Objects::nonNull)
                                     .collect(Collectors.toList());
        System.out.println(numbers); // 输出: [1, 2, 4]
    }
}

注意事项

  • 流的惰性求值:中间操作是惰性求值的,只有终端操作执行时才会触发实际的计算。
  • 不可重用:Stream 一旦使用完毕,不能再次使用。如果需要再次使用,需要重新生成 Stream。
  • 并行流的使用:并行流在某些情况下可以显著提高性能,但并非所有场景都适用,应根据实际情况进行选择。

结语

本文详细介绍了 Java Stream API 的基本用法和一些实践技巧。通过合理使用 Stream API,可以使代码更加简洁、高效。希望读者能够通过本文的介绍,更好地掌握和应用 Stream API。

责任编辑:赵宁宁 来源: 源话编程
相关推荐

2024-03-11 08:55:12

PythonCMD命令文件处理

2019-03-12 10:38:18

前端开发Nginx

2024-02-04 09:18:00

Python内存管理垃圾回收

2022-06-29 08:59:46

Java插件开发

2015-04-14 09:33:17

WatchKitAPP

2014-03-14 11:44:28

安卓开发者Android开发

2014-02-01 21:31:10

JavaScriptJS框架

2021-04-08 10:40:24

前端工具代码

2014-04-01 13:50:28

安卓Android开发者

2013-12-30 13:46:27

Android开发者

2013-07-19 09:47:57

White ElephHadoopLinkedIn

2014-04-18 13:20:34

Android安卓开发工具

2017-10-23 09:27:47

2022-09-15 17:08:20

JavaScripWeb开发

2015-07-21 10:42:17

API开发体验Yo

2015-07-20 09:16:42

iOSWatchKit开发

2012-02-13 10:21:11

Skala PreviiOS应用

2023-11-30 15:30:19

Python编程语言

2019-11-14 14:44:32

开发者工具

2015-09-06 16:22:48

JavaScriptSublimeText
点赞
收藏

51CTO技术栈公众号