加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

可变Scala集合的不可修改的视图

发布时间:2020-12-16 09:00:27 所属栏目:安全 来源:网络整理
导读:我有一个私有字段的类,它是一个可变集合.此特定实例中的字段是ArrayBuffer,但我的问题扩展到任何有限的,有序的随机访问集合类型.我想暴露这个字段而不允许其他人修改它.在 Java中我会添加一个方法,如: private ListT theList;public ListT getList() { retu
我有一个私有字段的类,它是一个可变集合.此特定实例中的字段是ArrayBuffer,但我的问题扩展到任何有限的,有序的随机访问集合类型.我想暴露这个字段而不允许其他人修改它.在 Java中我会添加一个方法,如:

private List<T> theList;

public List<T> getList() {
    return Collections.unmodifiableList(theList);
}

在Java中,我们只接受结果是一个没有完全实现List接口的List,因为#add和friends抛出UnsupportedOperationException.

在Scala中,我希望找到一个适当的特性,包括迭代器,大小和应用(用于按索引检索值),但没有变换器.这样的类型是否存在,我还没有找到?

解决方法

Scala集合库面向不变性,不变性不仅仅指您不允许修改给定集合的事实,而且还保证您不会被任何人修改过该集合.

所以你不能,你不应该得到像immutable.Seq这样的集合作为Scala中可变缓冲区的视图,因为它打破了这种保证.

但你可以像这样简单地实现不可修改的可变Seq的概念:

class UnmodifiableSeq[A](buffer: mutable.Seq[A]) extends mutable.Seq[A]{
    def update(idx: Int,elem: A) {throw new UnsupportedOperationException()}

    def length = buffer.length

    def apply(idx: Int) = buffer(idx)

    def iterator = buffer.iterator
}

用法:

val xs = Array(1,2,3,4)
val view = new UnmodifiableSeq(xs)
println(view(2)) >> 3
view(2) = 10 >> Exception in thread "main" java.lang.UnsupportedOperationException

编辑:

获取集合的不可修改视图的一种可能更好的方法是向下转换为collection.Seq,它不提供可变更新操作:

val xs = Array(1,3)
val view: Seq[Int] = xs //this is unmodifiable

或者如果你有自己的自定义可变类,则创建一个扩展Seq的包装器.

class UnmodifiableView[A](col: MutableCollection[A]) extends collection.Seq[A]{
    def length = col.length

    def apply(idx: Int) = col(idx)

    def iterator = col.iterator
}

scala.collection.Seq特性不保证不变性,但它也不允许任何修改操作,因此它看起来非常合适.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读