为了账号安全,请及时绑定邮箱和手机立即绑定

java流在创建不可变列表时是否会创建一些临时列表?

java流在创建不可变列表时是否会创建一些临时列表?

慕森王 2022-05-21 17:03:25
由于不能将任何元素添加到不可变列表中,我认为 java 流首先将元素收集到一个列表中,然后使用第一个列表中的元素创建一个新的不可变列表。因此,列表有两个实例,第一个实例可用于垃圾收集。所以,我的问题是如上所述,流是否实际上创建了两个列表对象?如果不是,流如何创建不可变列表?
查看完整描述

2 回答

?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

考虑以下示例:


List<String> people

         = getPeople().stream()

                      .collect(collectingAndThen(toList(), Collections::unmodifiableList));

对于这个例子,我使用的是Collections::unmodifiableList方法,所以让我们检查源代码:


/**

 * Returns an unmodifiable view of the specified list.  This method allows

 * modules to provide users with "read-only" access to internal

 * lists.  Query operations on the returned list "read through" to the

 * specified list, and attempts to modify the returned list, whether

 * direct or via its iterator, result in an

 * <tt>UnsupportedOperationException</tt>.<p>

 *

 * The returned list will be serializable if the specified list

 * is serializable. Similarly, the returned list will implement

 * {@link RandomAccess} if the specified list does.

 *

 * @param  list the list for which an unmodifiable view is to be returned.

 * @return an unmodifiable view of the specified list.

 */

public static <T> List<T> unmodifiableList(List<? extends T> list) {

    return (list instanceof RandomAccess ?

            new UnmodifiableRandomAccessList<>(list) :

            new UnmodifiableList<>(list));

}

正如@Pshemo 在评论中提到的那样,它UnmodifiableList可以作为列表的包装器,您还可以在源代码中检查该类包含一个列表:


 static class UnmodifiableList<E> extends UnmodifiableCollection<E>

                               implements List<E> {

     private static final long serialVersionUID = -283967356065247728L;

     final List<? extends E> list; // Here is the wrapped list


     UnmodifiableList(List<? extends E> list) {

         super(list);

         this.list = list;

     }

    ...

}

可以在此处找到用于提取这些代码的源代码。


所以回答你的问题:


流使用方法等Collections::unmodifiableList方法创建不可变列表

内部流不会在不同的列表中添加任何内容,因为它ImmutableList只是作为包装器工作Collection

您还可以查看文档和来源,以了解这些不可变相关方法和对象的工作原理。


查看完整回答
反对 回复 2022-05-21
?
牛魔王的故事

TA贡献1830条经验 获得超3个赞

任何实现都会以某种方式将元素累积到具有某种程度的可变性的结构中,然后返回一个无法修改的列表。

如何完成的细节取决于实现,但这里有几种可能性:

  • 元素被累积到一个ArrayList中,然后被复制到一个不可变列表中。

  • 元素被累积到一个ArrayList中,并返回一个防止修改的包装器(例如Collections.unmodifiableList。)由于没有其他对象引用原始ArrayList的 ,因此结果是不可变的。

  • 这些元素被累积到一些技术上不是列表的结构中,例如原始数组,并且该数组被复制或包装在不可变的列表对象中。

选择这些实现中的哪一个取决于Collector您调用的特定对象,例如Collectors.toList()ImmutableList.toImmutableList()。该实现的细节取决于该库的作者,他们可以使用任何这些策略。


查看完整回答
反对 回复 2022-05-21
  • 2 回答
  • 0 关注
  • 86 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号