Skip to content
程序猿DD程序猿DD
主页
最新发布
Java新特性
玩转IDEA
旧版博客open in new window
社区交流open in new window
  • Java 18

    • 指定UTF-8为默认字符集
      • 简单Web服务器
        • 新增@snippet标签
        • Java 17

          • 密封类
            • switch的模式匹配(预览)
            • Java 16

              • record类
                • instanceof增强
                  • Stream转List增强
                    • Stream.toList()和Collectors.toList()的区别
                    • Stream.toList()的性能比较
                    • Java 15

                      • 文本块
                        • 隐藏类
                        • Java 14

                          • switch表达式增强
                          • Java 13

                            • Java 12

                              • Java 11

                                • 移除JavaEE和CORBA模块
                                • Java 10

                                  • 局部变量的类型推断
                                  • Java 9

                                    • 交互式编程环境JShell
                                      • 不可变集合的快捷创建方法

                                      Java Stream转List可以直接toList而不必collect了?

                                      程序猿DD原创2022年5月21日
                                      • Java
                                      • Java 16
                                      大约 2 分钟

                                      此页内容
                                      • Stream.toList()和Collectors.toList()的区别

                                      # Java Stream转List可以直接toList而不必collect了?

                                      前几天分享了如何优雅的调试Java Stream操作。然后有小伙伴对其中的一段代码有一些疑问:“为啥你的stream可以直接toList而不必collect?” 下面就给大家解读下这个内容。

                                      疑问的代码片段如下:

                                      public class StreamTest {
                                      
                                          @Test
                                          void test() {
                                              List<String> list = List.of("blog.didispace.com", "spring4all.com", "openwrite.cn", "www.didispace.com");
                                      
                                              List<String> result = list.stream()
                                                      .filter(e -> e.contains("didispace.com"))
                                                      .filter(e -> e.length() > 17)
                                                      .toList();
                                      
                                              System.out.println(result);
                                          }
                                      
                                      }
                                      

                                      小伙伴疑问的就是第10行:toList()。实际上这个方法是Java 16才支持的一个方法,它可以直接将Stream转化成List。而因为目前很多小伙伴还在用Java 8,所以在介绍如何调试Stream的时候,直接用我这段代码可能会碰到这个问题。

                                      那么Java 8的用户怎么写呢?我看到也有网友直接给出了Java 8下的方法,就如下面这样:

                                      List<String> result = list.stream()
                                          .filter(e -> e.contains("didispace.com"))
                                          .filter(e -> e.length() > 17)
                                          .collect(Collectors.toList());
                                      

                                      # Stream.toList()和Collectors.toList()的区别

                                      就完整上面的代码逻辑,这样的替换完全是可以的,但是虽然最终都转成List了,他们之间是否还有区别呢?

                                      这里我单独拉出来说,显然肯定是有区别的。

                                      通过查看Stream.toList()的源码:

                                      default List<T> toList() {
                                          return (List<T>) Collections.unmodifiableList(new ArrayList<>(Arrays.asList(this.toArray())));
                                      }
                                      

                                      我们可以发现,它所创建的是一个unmodifiableList不可变的List。

                                      而使用Stream.collect(Collectors.toList())创建出来的则是一个普通的List,是可以做增删改操作的。

                                      那么如果用Collectors也要创建不可变的List要怎么写呢?其实也很简单,只需要调用Collectors.toUnmodifiableList()就可以了。所以与本文开头等价代码替换可以这样写:

                                      List<String> result = list.stream()
                                          .filter(e -> e.contains("didispace.com"))
                                          .filter(e -> e.length() > 17)
                                          .collect(Collectors.toUnmodifiableList());
                                      

                                      但要注意的是,这个方法Java 8里也没有,是Java 10才开始支持的。

                                      好了,今天的分享就到这里,你学会了吗?

                                      本期视频:https://www.bilibili.com/video/BV16Y411F7Pm/open in new window

                                      如果您学习过程中如遇困难?可以加入我们超高质量的技术交流群open in new window,参与交流与讨论,更好的学习与进步!另外,不要走开,关注我,持续更新Java新特性专栏open in new window!

                                      上次编辑于: 2022/5/22 16:36:15
                                      贡献者: dd
                                      上一页
                                      instanceof增强
                                      下一页
                                      Stream.toList()的性能比较
                                      © 2016 - 2022 didispace.com 版权所有
                                      沪ICP备14037150号-3
                                      Copyright © 2022 程序猿DD