Java 谷歌和谷歌的区别是什么;s ImmutableList和Collections.unmodifiableList()?

Java 谷歌和谷歌的区别是什么;s ImmutableList和Collections.unmodifiableList()?,java,collections,comparison,guava,Java,Collections,Comparison,Guava,从ImmutableList javadocs: 不像 Collections.unmodifiableList(java.util.List), 这是一个独立的视图 仍然可以更改的集合 ImmutableList的实例包含其 拥有私人数据,永远不会 改变不可变列表很方便 对于公共静态最终列表 (“常量列表”)并允许您 轻松制作一个“防御性副本” 列表由 来电者 这是否意味着: 如果我有不可变的维度对象列表(例如),那么我不能更改其中的任何维度对象 如果我有Collections.unmodif

从ImmutableList javadocs:

不像 Collections.unmodifiableList(java.util.List), 这是一个独立的视图 仍然可以更改的集合 ImmutableList的实例包含其 拥有私人数据,永远不会 改变不可变列表很方便 对于公共静态最终列表 (“常量列表”)并允许您 轻松制作一个“防御性副本” 列表由 来电者

这是否意味着:

  • 如果我有不可变的维度对象列表(例如),那么我不能更改其中的任何维度对象
  • 如果我有Collections.unmodifiableList(list)维度对象,那么我不仅可以添加或删除任何对象,还可以更改它们(例如调用setDimension(width,height)方法)

  • 否,不变性仅应用于
    集合中对象的数量和引用,而不解决放入
    集合中对象的可变性

    与标准JDK
    集合相比,不可变列表的优势在于,通过使用
    不可变列表
    ,您可以保证引用的对象、它们的顺序和列表的大小不会从任何来源更改。使用
    Collections.unmodifiableList
    如果其他内容引用了基础列表,则即使您引用了不可修改列表,该代码也可以修改该列表


    但是,如果您想要真正的不可变性,则必须使用不可变对象填充列表。

    使用
    集合。不可变列表在列表周围创建一个包装。如果基础列表发生更改,则不可修改列表的视图也会发生更改


    正如文档所说,谷歌的代码创建了一个副本。这是一个更昂贵的计算,消耗更多的内存,但如果有人更改原始列表,它不会影响不可变列表

    这两种方法都不会阻止您更改列表中的对象、其字段或字段字段等

  • 否,仍然可以修改包含的单个对象。集合实际上只是存储对所包含对象的引用,而不是每个对象的完整副本
  • 您可以通过修改名为Collections的父集合来修改列表。上的unmodifiableList(list)。但是,可以使用setDimension更改存储的列表元素
    ImmutableList
    类似于
    集合。不可修改列表(新的ArrayList(list))
    。请注意,新创建的
    ArrayList
    分配给字段或变量。

    您可能还想看看(番石榴的
    集合.unmodifiableSet()
    不可变集
    之间有什么区别)。

    @Vuntic如果该类是真正不可变的,则其字段声明为final,反射不能改变这一点。@Yishai,反射可以修改最终字段。试试看。@Vuntic,是否可以访问设置?这取决于安全管理器;)@Vuntic,当我试图修改最终字段而不设置setAccessable时,会出现异常。你在想什么?顺便说一句,这个问题也没有提到反思;)@我知道我已经晚了7年才开始这段对话。。。但是对于公共记录,您可以通过首先使用反射删除最终修改器来修改最终字段。不过,它只对对象有效,对原语无效。“正如文档所说,谷歌的代码创建了一个副本。”它可能会创建一个副本。如果原始数据结构也是一个不可变的数据结构,那么它实际上可能能够重用它。因此,如果您广泛使用
    ImmutableList
    ,您会经常遇到这种情况,并且最终不需要进行大量复制。您可能还想看看