Scala 类库和可见性说明

2017/11/16 Scala

Scala 类库和可见性说明

集合类总览

名称 描述
collection 基本包,所有特征和对象,包括子包中的所有定义。
collection.concurrent 并发的Map和原子的无锁的TridMap
collcetion.convert 定义了Java集合类来包装Scala集合的类型,以及用scala集合类来包装java集合类的类型,这个包中的类型多数是用来做隐式转换的
collection.generic 定义了用来构建特定集合的组件
collection.immutable 常用不可变集合
collection.mutable 常用可变集合组件
collection.parallel 支持并行的集合组件
collection.parallel.imutable 并行的不可变集合组件
collection.parallel.mutable 并行的可变集合组件

常用不可变集合

名称 描述
BitSet 非负整数集合,表示大小可变的比特数组
HashMap 字典散列的map
HashSet 集合
List 相连列表的trait,伴随对象有apply和其它工厂方法
ListMap 用列表实现的不可变map
ListSet 用列表实现的Set
Map 所有不可变map的trait,伴随对象有apply方法
Nil 空列表对象
NumbericRange Range的推广,必须提供完整的类型实现
Queue 不可变FIFO队列
Seq 不可变序列trait,伴随有apply方法
Set trait,不可变集合定义了操作,伴随有apply方法
SortedMap trait,包含可按特定顺序的迭代器,伴随有apply
Stack 不可变的LIFO栈
Stream 对元素惰性求值的列表
TreeMap 不可变Map,底层用红黑树实现
TreeSet 不可变集合,用红黑树实现
Vector 不可变,支持下标的序列的默认实现

常用可变集合

名称 描述
AnyRefMap 为AnyRef类型的Key准备的集合,大部分操作比hashMap快
ArrayBuffer 用数组实现的缓冲区,追加、更新与随机访问的均摊时间复杂度为 O (1),头部插入和删除操作的复杂度为 O (n )
ArrayOps 对Java数组的包装类,实现了序列操作
ArrayStack 数组实现的栈,比通用的栈快
BitSet 同上一节
HashMap 同上
HashSet 同上
HashTable 实现基于hashmap的可变集合的trait
ListMap 基于列表的map
LinkedHashMap 可以按照插入顺序访问的的map
LinkedHashSet 可以按照插入顺序访问的Set
LongMap Long为Key的Map,大部分操作比HashMap快
Map 可变trait,伴随apply
MultiMap 可变map,一个Key多个值
PriorityQueue 基于堆的,可变优先级序列,对于类型A,必须有隐含的Ordering[A]
Queue 可变的FIFO
Seq trait,有伴随
Set trait,有伴随
SotedSet trait,包含特定顺序迭代的迭代器,有伴随
Stack LIFO栈
TreeSet 可变类型,用红黑树
WeakHashMap 可变map,包含弱经用类型,元素没有强引用时就会被删掉
WrappedArray 对Java数组的包装,支持序列操作

库的设计 模式

在集合的设计中使用了三个最重要的设计方法。

  1. 用 Builder 抽象了构造。
  2. 用 CanBuildFrom 提供隐含的工厂,用于构造适合给定上下文的生成器实例。
  3. Like 特征为 Builder 和 CanBuildFrom 添加必须的返回值类型参数,并提供大部分的方法实现。(如SeqLike特征)

builder

//builder declaration
trait Builder[-Elem,+To]{
	def += (elem:Elem):Builder.this.type		//singleton
	def clear()
	def result():To
	//...
}

class ListBuilder[T] extends Builder[T,List[T]]{	//输入的参数可以逆变 ,但是输出只能协变
	private var stoorage = Vector.empty[T]
	
	ddef += (elem:T)={
		storage=storage :+ elem
		this
	}
	
	def clear():Unit={
		storage=Vector.empty[T]
	}
	
	def result():List[T]= storage.toList
	
}

这是常见的Builder用法

CanBuildFrom

这个机制中包含有隐式转换,从中处理不同数据的情况。如:

trait TraversableLike[+A,+Repr] extends ... {
	...
	def map[B,That](f:A=>B){
		implicit bf: CanBuildFrom[Repr,B,That]:That ={ ... }
	}
}

That 是要创建的目标集合的类型参数。

值类型的特化

scala对值类型和引用类型有统一的处理,scala可以用值类型参数化实例。如List[Int],这样的好处是原生类型在内存中是连续分布的,可以提高缓存命中率,为某些算法提高性能。 尽管 Scala 允许我们声明值类型的容器,但这并不能解决问题。由于类型擦除的存在以及 JVM 很难记忆容器中元素类型的事实,元素被认为是 Object 类型,所有的元素类型共有同一种容器的实现版本。所以 List[Double] 依然需要使用例如 Java 包装后的Double的类型。 为也解决这个问题,scala中引入了@specialized标记实现这个目的。会使编译器为标记中列出的值类型算成自定义实现。如:

class SpecialVactor[@specialized(Int ,Double,Boolean) T]{...}

缺陷也是有的: 引入这个标记后,会引入很多自动生成的代码,所以大量使用会使得库变大。如果一个字段在原始容器中被声明为泛型类型,那么它在特化时不会转为原生类型的字段。相反,编译器会再生成一个相应原生类型的重复字段,从而带来错误。另一个缺陷是,特化的容器被实现为原始通用容器的子类。当通用容器及其子类都是特化类型时,就无法工作了。特化的类型应该与父类型具有同样的继承关系,但由于 JVM 的单继承模型,这种相同的继承关系得不到支持。 所以@specialized用得很少,主要用在 FunctionN 、TupleN 、ProductN 类型或者少数集合中。

nimiboxing

这是编译器插件;用法是和@specilized一致的。如:

class SpecialVector[@miniboxed(Int, Double, Boolean) T] {...}

Miniboxing 将泛型容器改为拥有两个子类型的 trait,一个子类用于值类型,另一个子类用于引用类型,从而降低了代码膨胀。表示原生类型的子类 注意到,一个 8 比特的值可以装下任何一个原生类型。利用这一点,该类增加了一个“标签”,用于表示这 8 比特应被解释成的原生类型。所以, 该子类表现得像一个带标签的联合体,不再需要让每个原生类型都拥有一个单独的实例。引用类型不受影响。 通过将原始容器改为 trait,它所存在的所有继承关系都得到了保持。例如:我们有两个参数化的容器 C[T] 和 D[T] ,其中 D[T] 类继承了 C[T] ,并且这两个类型都做了特化,那么从概念上看,生成的代码会是这样:

trait C[T]
class C_primitive[T] extends C[T]
class C_AnyRef[T] extends C[T]

trait D[T] extends C[T]
class D_primitive[T] extends C_primitive[T] with D[T]
class D_anyref[T] extends C_Anyref[T] with D[T]

可见性

作用域总结

可见性 关键字 描述
public 字任何作用域内均能访问公有成员或公有类型,public 可见性无视所有限制
protected protected 受保护(protected)成员对本类型、继承类型以及嵌套类型可见。而受保护的类型则只对相同包内或子包内的某些类型可见
private private 私有(private)成员只对本类型和嵌套类型可见,而且可以访问私有成员的类型必须位于相同包内
作用域内受保护 protected[scope] 只能在某一作用域内可见,该作用域可以是包作用域、类型作用域或 this 作用域(这意味着如果成员使用了该可见性,this 代表了相同实 例,如果类型使用该可见性,则 this 表示该类型所在的包)。
作用域内私有 private[scope] 除了对具有继承关系的类的可见性不同之外,与作用域内受保护可见性相同

Scala 的可见性声明非常灵活,而且这些声明表现一致。从实例级(private[this] )到包级(private[P] ,P 为对应的包名),这些可见 性规则在各种作用域里均提供了细粒度控制约束。

小结

对工具的掌握程序越高,越能更好的使用程序,从而获得更高的效率。

Show Disqus Comments

Search

    Table of Contents