从公共方法

时间:2015-10-12 08:58:33

标签: java

我有一个方法:

public List getDocuments(Long orgClientId, long userId) {

    // do stuff
    List list = new ArrayList();
    // do stuff to fill the list. The list will be of hashmaps.

    return list;
}

我不希望在此方法之外修改我的列表。那我该怎么回事呢?克隆吗?或者只是返回一个像

这样的新实例
return new ArrayList<>(list);

会这样做吗?

2 个答案:

答案 0 :(得分:11)

因此,你可以表面上不可修改:

return Collections.unmodifiableList(list)

这包装了列表,以便调用任何突变方法都会导致异常。

但是,如果有人修改了列表,那么真的对你来说真的很重要吗?每次调用此方法时,您都会返回一个新的列表实例,因此两个调用者获取相同实例并且必须处理突变之间的交互时没有问题。

无论你采取什么步骤试图使其不可修改,我都可以自己将列表复制到一个可修改的容器中。

如果你给我一些我无法检测到它是否可变的东西,对我来说也很不方便 - 看起来像List;查看是否可以改变它的唯一方法是调用变异方法。那是运行时故障,这使它成为PITA。

更新,添加替代方案。

Collections.unmodifiableList的替代方法类似于番石榴ImmutableList:这可能比Collections.unmodifiableList更快,因为它不仅仅通过包装提供现有列表的不可修改的视图,而是提供List的自定义实现,禁止变异(间接较少)。

这样做的好处是您可以返回ImmutableList而不仅仅是List返回的Collections.unmodifiableList:这样您就可以向调用方提供更多类型的信息&# 39;改变它。 ImmutableList(以及它的兄弟姐妹,如ImmutableSet)标记了变异方法@Deprecated,因此您的IDE可以警告您,如果您可能正在做某事。

来电者可能选择忽略该信息(他们将结果分配给List,而不是ImmutableList),但这是他们的选择。

答案 1 :(得分:1)

这个想法是umodifiableCollection返回的对象不能直接改变,但可以通过其他方式改变(有效地直接改变内部集合)。

List<String> list = new ArrayList<String>();
list.add("One");
list.add("Two");
list.add("Three");
List<String> unmodifiableList = Collections.unmodifiableList(list);

   // this doesn't throw an exception since it's using the add
   // method of the original List reference, which is no problem
list.add("Four");
System.out.println(unmodifiableList);

  // this, however, throws an exception
unmodifiableList.add("Five");
  

unmodifiableList返回指定列表的不可修改视图。   该方法允许模块为用户提供&#34;只读&#34;进入   内部清单。对返回列表的查询操作&#34;通读&#34;   到指定的列表,并尝试修改返回的列表,   无论是直接还是通过其迭代器,都会产生一个   UnsupportedOperationException异常。返回的列表将是可序列化的   如果指定的列表是可序列化的。