JavaStream
    Java 16中的Stream增强,可以直接通过toList()来转换成List。
    主要涉及下面这几种转换方式:

    1. list.stream().toList();
    2. list.stream().collect(Collectors.toList());
    3. list.stream().collect(Collectors.toUnmodifiableList());

    那么Stream.toList()Collectors.toList()的区别是什么?哪个性能好?
    处理结果的区别:

    • Stream.toList()返回的List是不可变List,不能增删改
    • Collectors.toList()返回的是个普通的List,可以增删改
    • Collectors.toUnmodifiableList()返回的List是不可变List,不能增删改

    而至于性能的话,来测试一下,看看哪个性能更好。

    1. @BenchmarkMode(Mode.All)
    2. @Fork(1)
    3. @State(Scope.Thread)
    4. @Warmup(iterations = 20, time = 1, batchSize = 10000)
    5. @Measurement(iterations = 20, time = 1, batchSize = 10000)
    6. public class BenchmarkStreamToList {
    7. @Benchmark
    8. public List<Integer> streamToList() {
    9. return IntStream.range(1, 1000).boxed().toList();
    10. }
    11. @Benchmark
    12. public List<Integer> collectorsToList() {
    13. return IntStream.range(1, 1000).boxed().collect(Collectors.toList());
    14. }
    15. @Benchmark
    16. public List<Integer> streamToList() {
    17. return IntStream.range(1, 1000).boxed().toList();
    18. }
    19. }

    结果报告:

    1. Benchmark Mode Cnt Score Error Units
    2. BenchmarkStreamToList.collectorsToList thrpt 20 24.422 ± 0.268 ops/s
    3. BenchmarkStreamToList.collectorsToUnmodifiableList thrpt 20 22.784 ± 0.599 ops/s
    4. BenchmarkStreamToList.streamToList thrpt 20 31.779 ± 1.732 ops/s
    5. BenchmarkStreamToList.collectorsToList avgt 20 0.045 ± 0.006 s/op
    6. BenchmarkStreamToList.collectorsToUnmodifiableList avgt 20 0.062 ± 0.035 s/op
    7. BenchmarkStreamToList.streamToList avgt 20 0.040 ± 0.028 s/op
    8. BenchmarkStreamToList.collectorsToList sample 445 0.046 ± 0.002 s/op
    9. BenchmarkStreamToList.collectorsToList:collectorsToList·p0.00 sample 0.039 s/op
    10. BenchmarkStreamToList.collectorsToList:collectorsToList·p0.50 sample 0.041 s/op
    11. BenchmarkStreamToList.collectorsToList:collectorsToList·p0.90 sample 0.057 s/op
    12. BenchmarkStreamToList.collectorsToList:collectorsToList·p0.95 sample 0.073 s/op
    13. BenchmarkStreamToList.collectorsToList:collectorsToList·p0.99 sample 0.102 s/op
    14. BenchmarkStreamToList.collectorsToList:collectorsToList·p0.999 sample 0.150 s/op
    15. BenchmarkStreamToList.collectorsToList:collectorsToList·p0.9999 sample 0.150 s/op
    16. BenchmarkStreamToList.collectorsToList:collectorsToList·p1.00 sample 0.150 s/op
    17. BenchmarkStreamToList.collectorsToUnmodifiableList sample 460 0.044 ± 0.001 s/op
    18. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p0.00 sample 0.042 s/op
    19. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p0.50 sample 0.044 s/op
    20. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p0.90 sample 0.046 s/op
    21. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p0.95 sample 0.047 s/op
    22. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p0.99 sample 0.051 s/op
    23. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p0.999 sample 0.057 s/op
    24. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p0.9999 sample 0.057 s/op
    25. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p1.00 sample 0.057 s/op
    26. BenchmarkStreamToList.streamToList sample 655 0.031 ± 0.001 s/op
    27. BenchmarkStreamToList.streamToList:streamToList·p0.00 sample 0.030 s/op
    28. BenchmarkStreamToList.streamToList:streamToList·p0.50 sample 0.031 s/op
    29. BenchmarkStreamToList.streamToList:streamToList·p0.90 sample 0.032 s/op
    30. BenchmarkStreamToList.streamToList:streamToList·p0.95 sample 0.033 s/op
    31. BenchmarkStreamToList.streamToList:streamToList·p0.99 sample 0.035 s/op
    32. BenchmarkStreamToList.streamToList:streamToList·p0.999 sample 0.037 s/op
    33. BenchmarkStreamToList.streamToList:streamToList·p0.9999 sample 0.037 s/op
    34. BenchmarkStreamToList.streamToList:streamToList·p1.00 sample 0.037 s/op
    35. BenchmarkStreamToList.collectorsToList ss 20 0.043 ± 0.001 s/op
    36. BenchmarkStreamToList.collectorsToUnmodifiableList ss 20 0.045 ± 0.004 s/op
    37. BenchmarkStreamToList.streamToList ss 20 0.031 ± 0.001 s/op

    从报告中可以看到:

    • 吞吐量:streamToList > collectorsToList > collectorsToUnmodifiableList
    • 平均耗时:streamToList > collectorsToList > collectorsToUnmodifiableList
    • p0.9999耗时:streamToList > collectorsToUnmodifiableList > collectorsToList
    • 冷启动耗时:streamToList > collectorsToList > collectorsToUnmodifiableList

    所以,Stream.toList()的性能要各方面都要好于Collectors.toList()Collectors.toUnmodifiableList()
    再放大一些数据量,试试:

    1. @Benchmark
    2. public List<Integer> streamToList() {
    3. return IntStream.range(1, 10000).boxed().toList();
    4. }
    5. @Benchmark
    6. public List<Integer> collectorsToList() {
    7. return IntStream.range(1, 10000).boxed().collect(Collectors.toList());
    8. }
    9. @Benchmark
    10. public List<Integer> streamToList() {
    11. return IntStream.range(1, 10000).boxed().toList();
    12. }

    结果报告:

    1. Benchmark Mode Cnt Score Error Units
    2. BenchmarkStreamToList.collectorsToList thrpt 20 2.186 ± 0.162 ops/s
    3. BenchmarkStreamToList.collectorsToUnmodifiableList thrpt 20 2.184 ± 0.042 ops/s
    4. BenchmarkStreamToList.streamToList thrpt 20 3.538 ± 0.058 ops/s
    5. BenchmarkStreamToList.collectorsToList avgt 20 0.426 ± 0.004 s/op
    6. BenchmarkStreamToList.collectorsToUnmodifiableList avgt 20 0.469 ± 0.016 s/op
    7. BenchmarkStreamToList.streamToList avgt 20 0.293 ± 0.008 s/op
    8. BenchmarkStreamToList.collectorsToList sample 58 0.448 ± 0.049 s/op
    9. BenchmarkStreamToList.collectorsToList:collectorsToList·p0.00 sample 0.414 s/op
    10. BenchmarkStreamToList.collectorsToList:collectorsToList·p0.50 sample 0.422 s/op
    11. BenchmarkStreamToList.collectorsToList:collectorsToList·p0.90 sample 0.458 s/op
    12. BenchmarkStreamToList.collectorsToList:collectorsToList·p0.95 sample 0.560 s/op
    13. BenchmarkStreamToList.collectorsToList:collectorsToList·p0.99 sample 1.160 s/op
    14. BenchmarkStreamToList.collectorsToList:collectorsToList·p0.999 sample 1.160 s/op
    15. BenchmarkStreamToList.collectorsToList:collectorsToList·p0.9999 sample 1.160 s/op
    16. BenchmarkStreamToList.collectorsToList:collectorsToList·p1.00 sample 1.160 s/op
    17. BenchmarkStreamToList.collectorsToUnmodifiableList sample 60 0.458 ± 0.004 s/op
    18. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p0.00 sample 0.447 s/op
    19. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p0.50 sample 0.455 s/op
    20. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p0.90 sample 0.471 s/op
    21. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p0.95 sample 0.482 s/op
    22. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p0.99 sample 0.492 s/op
    23. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p0.999 sample 0.492 s/op
    24. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p0.9999 sample 0.492 s/op
    25. BenchmarkStreamToList.collectorsToUnmodifiableList:collectorsToUnmodifiableList·p1.00 sample 0.492 s/op
    26. BenchmarkStreamToList.streamToList sample 78 0.293 ± 0.012 s/op
    27. BenchmarkStreamToList.streamToList:streamToList·p0.00 sample 0.277 s/op
    28. BenchmarkStreamToList.streamToList:streamToList·p0.50 sample 0.284 s/op
    29. BenchmarkStreamToList.streamToList:streamToList·p0.90 sample 0.309 s/op
    30. BenchmarkStreamToList.streamToList:streamToList·p0.95 sample 0.377 s/op
    31. BenchmarkStreamToList.streamToList:streamToList·p0.99 sample 0.459 s/op
    32. BenchmarkStreamToList.streamToList:streamToList·p0.999 sample 0.459 s/op
    33. BenchmarkStreamToList.streamToList:streamToList·p0.9999 sample 0.459 s/op
    34. BenchmarkStreamToList.streamToList:streamToList·p1.00 sample 0.459 s/op
    35. BenchmarkStreamToList.collectorsToList ss 20 0.474 ± 0.133 s/op
    36. BenchmarkStreamToList.collectorsToUnmodifiableList ss 20 0.493 ± 0.099 s/op
    37. BenchmarkStreamToList.streamToList ss 20 0.325 ± 0.056 s/op

    从报告中可以看到

    • 吞吐量:streamToList > collectorsToList > collectorsToUnmodifiableList
    • 平均耗时:streamToList > collectorsToList > collectorsToUnmodifiableList
    • p0.9999耗时:streamToList > collectorsToUnmodifiableList > collectorsToList
    • 冷启动耗时:streamToList > collectorsToList > collectorsToUnmodifiableList

    所以,即使集合内的元素增大,Stream.toList()的性能在各方面依然都要好于Collectors下的方法。