10 个 Java Stream (数据流)技巧

1 人赞同了该文章

【参考文献】

文章:10 Java Stream Tips — Must Read
作者:Sivaram Rasathurai
上述译文仅供参考,具体内容请查看上面链接,解释权归原作者所有。

Java Stream API 就像 Java 开发人员的瑞士军刀,它用途广泛、结构紧凑,可以轻松处理各种任务。

它为开发人员提供了一种功能性和声明性的方式来表达复杂的数据转换和操作,使代码更加简洁、更具表现力。

但是,能力越大,责任越大,要有效地使用流 API,就必须扎实地了解最佳实践和常见陷阱。

今天,我们将探讨使用 Java Stream API 的一些最佳实践,并向您展示如何充分释放这一神奇工具的潜力。

无论您是初学者还是经验丰富的开发人员,您都一定能在使用 Java 流的过程中学到一些令人兴奋的新知识。

1. 使用primitive streams(原始流)提高性能

在处理 int、long 和 double 等primitiv类型时,应使用 IntStream、LongStream 和 DoubleStream 等primitive stream,而不是 Integer、Long 和 Double 等streams of boxed(盒装)类型流。primitive streams避免了装箱和拆箱的成本,因此能提供更好的性能。

var array = new int[]{1, 2, 3, 4, 5};
var sum = Arrays.stream(array)
               .sum();

2. 避免嵌套stream

最佳做法是避免嵌套stream,因为这会导致代码难以阅读和理解。相反,应尽量将问题分解成更小的部分,并使用中间集合或局部变量来存储中间结果。

var list1 = Arrays.asList("apple", "banana", "cherry");
var list2 = Arrays.asList("orange", "pineapple", "mango");
var result = Stream.concat(list1.stream(), list2.stream())
                  .filter(s -> s.length() > 5)
                  .collect(Collectors.toList());

3. 谨慎使用parallel streams(并行流)

parallel streams可以在处理大量数据时提供更好的性能,但也会带来开销和竞争条件。谨慎使用parallel streams,并考虑数据大小、操作复杂程度和可用处理器数量等因素。

var list = Arrays.asList(1, 2, 3, 4, 5);
var sum = list.parallelStream().reduce(0, Integer::sum);

4. 使用lazy evaluation(延迟评估)提高性能

The Stream API支持延迟评估,即在调用终端操作之前不执行中间操作。作为最佳实践,请尽量使用延迟评估,通过减少不必要的计算来提高性能。

var list = Arrays.asList(1, 2, 3, 4, 5);
var result = list.stream()
                 .filter(n -> n > 3)
                 .findFirst();

5. 避免副作用

The Stream API的设计目的是对数据执行功能性操作。避免引入副作用,如修改stream之外的变量或执行 I/O 操作,因为这会导致不可预测的行为,并降低代码的可读性。

var list = Arrays.asList("apple", "banana", "cherry");
var count = 0;
list.stream()
    .filter(s -> s.startsWith("a"))
    .forEach(s -> count++);
Use streams with immutable objects: The Stream API works best with immutable objects. Using immutable objects ensures that the state of the stream is not modified during processing, which can lead to more predictable behavior and better code readability.
Example:
less
Copy code
var list = Arrays.asList("apple", "banana", "cherry");
var result = list.stream()
                 .map(String::toUpperCase)
                 .collect(Collectors.toList());

6.使用不可变对象的stream

The Stream API与不可变对象配合使用效果最佳。使用不可变对象可确保stream的状态在处理过程中不会被修改,从而提高行为的可预测性和代码的可读性。

var list = Arrays.asList("apple", "banana", "cherry");
var result = list.stream()
                 .map(String::toUpperCase)
                 .collect(Collectors.toList());

7.在 map() 之前使用 filter() 可避免不必要的处理

如果您的stream可能包含大量不符合条件的元素,请在 map() 之前使用 filter() 以避免不必要的处理。这可以提高代码的性能。

var list = Arrays.asList(1, 2, 3, 4, 5);
var filteredList = list.stream()
                       .filter(i -> i % 2 == 0)
                       .map(i -> i * 2)
                       .collect(Collectors.toList());

8. 方法引用优先于 lambda 表达式

与使用 lambda 表达式相比,方法引用可以使代码更加简洁易读。如果可以使用方法引用代替 lambda 表达式,请优先使用方法引用。

var list = Arrays.asList(1, 2, 3, 4, 5);
var sum = list.stream()
              .reduce(0, Integer::sum);

9. 使用 distinct() 删除重复内容

如果 stream 中可能包含重复元素,可使用 distinct() 操作将其删除

var list = Arrays.asList(1, 2, 3, 3, 4, 5, 5);
var distinctList = list.stream()
                       .distinct()
                       .collect(Collectors.toList());

10. 谨慎使用 sorted()

sorted()操作可能很昂贵,尤其是对于large streams(大数据流)。请谨慎使用,只有在必要时才使用。如果知道输入数据已经排序,可以跳过此操作。

var list = Arrays.asList(3, 2, 1);
var sortedList = list.stream()
                     .sorted()
                     .collect(Collectors.toList());

正如我前面所说,Java Stream API 是一个强大而灵活的工具,可以大大简化数据处理任务的代码。

通过遵循本文讨论的提示,您可以确保您的代码既高效又有效。不过,重要的是要记住,有效使用 Java Stream API 需要对其功能和局限性有扎实的了解。

因此,不要止步于此!继续学习和探索 Java Stream API 的世界,释放它的全部潜能。如果您有任何问题或见解,我鼓励您在下面的评论部分与我们分享。让我们继续交流,互相帮助,成为更好的 Java 开发人员。


⚠️:文章翻译上如有语法不准确或者内容纰漏,欢迎各位评论区指正。


【关于TalkX】

TalkX是一款基于GPT实现的IDE智能开发插件,专注于编程领域,是开发者在日常编码中提高编码效率及质量的辅助工具,TalkX常用的功能包括但不限于:解释代码、中英翻译、性能检查、安全检查、样式检查、优化并改进、提高可读性、清理代码、生成测试用例以及有趣的图表转账等。

TalkX建立了全球加速网络,不需要考虑网络环境,响应速度快,界面效果和交互体验更流畅。并为用户提供了OpenAI的密钥,不需要ApiKey,不需要自备账号,不需要魔法。

TalkX产品支持:JetBrains (包括 IntelliJ IDEA、PyCharm、WebStorm、Android Studio)、HBuilder、VS Code、Goland.