繁体   English   中英

有效使用Collections.unmodifiable *()

[英]Effective use of Collections.unmodifiable*()

在考虑效率,代码可读性和其他标准时,更好的方式是公开集合的只读视图? 它使从效率的观点任何真正的区别使用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);
    }
}

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

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

如果只是在每次有人提示GUI数据发生了变化时才取出一个集合,那么这种情况相对较少发生,我预计 - 不会出现“每秒数十万次”的范围瓶颈。 我希望无论代码是什么调用,这可能会比创建不可修改列表所做的工作要多得多。

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

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

不要做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!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM