有效使用Collections.unmodifiable *()

时间:2014-05-29 06:13:20

标签: java collections

在考虑效率,代码可读性和其他标准时,更有利于公开集合的只读视图的方法是什么?从效率的角度来看,使用methodA代替methodB会有什么不同吗?请考虑可能经常访问list的情况 - 例如gui table的数据模型。

我认为Collectionss.umodifiebleList()始终会创建一个新对象,这是正确的吗?

class A{
    List<Object> list = new ArrayList<Object>();
    List<Object> listReadOnly = Collections.unmodifiableList(list);

    List<Object> methodA(){
        return listReadOnly;
    }

    List<Object> methodB(){
        return Collections.unmodifiableList(list);
    }
}

2 个答案:

答案 0 :(得分:10)

是的,Collections.unmodifiableList每次都会创建一个新对象 - 但这是一个非常便宜的操作。 (没有太多工作要做。)

我不确定GUI的数据模型是否可能一遍又一遍地获取集合 - 它显然会获取集合然后迭代它,但这是另一回事。

如果只是在每次有人提示GUI数据发生变化时才提取集合,那么相对很少发生,我期望 - 不是“成千上万次”每秒“这将成为瓶颈的范围。我希望无论代码是什么调用,这可能会比创建不可修改列表所做的工作多得多。

基本上,这感觉就像微观优化太过分了,除非你有证据表明它会导致问题。一如既往,你应该:

  • 定义性能要求
  • 以最简单的方式编写符合其他要求的代码
  • 编写测试以检查您是否符合性能要求
  • 如果您目前不符合这些要求,请仔细确定瓶颈所在(无论是使用分析器还是其他技术)
  • 以尽可能小的可读性损失修复这些瓶颈
  • 泡沫,冲洗,重复

答案 1 :(得分:5)

不要methodA,因为你必须在列表之间保持状态,这在多线程环境中可能很棘手,即使对于单线程环境也是如此。

methodB,让JDK整理效率(它非常快)。

注意:除非列表中的元素本身是不可变的,否则methodB并不完全安全,因为虽然 list 可能是不可修改的,但其元素本身可能已被修改。考虑:

List<Date> list = new ArrayList<Date>();
list.add(new Date());
List<Date> dates = Collections.unmodifiableList(list);
Date date = dates.get(0);
date.setTime(0);  // The date in the original list has now changed!