目标是使用Scala集合,其中不需要迭代或递归计算大小。
例如List
被证明是递归构造(例如考虑https://stackoverflow.com/a/8197826/3189923),并且为了获得大小,有必要迭代它;即对列表中元素数量的O(N)
操作。
因此要问这个操作是O(1)
哪个集合?
非常感谢。
答案 0 :(得分:7)
主要不可变集合的方法size
的成本(根据代码快速查看):
Seq:
LinearSeq:
List - O(N)
Stream - O(N)*
Queue - O(N) // Implemented using List
Stack - O(N)* // Implemented using List, with additional complexity
IndexedSeq:
Vector - O(1)
NumericRange - O(1)
Array - O(1) // WrappedArray, ArrayOps
String - O(1) // WrappedString, StringOps
Range - O(1)
Set:
HashSet - O(1) // HashSet.HashTrieSet
TreeSet - O(N) // RedBlackTree.count - recursive with stack usage
BitSet - O(Max)* // fast enough. O(1) for collections of small ints
ListSet - O(N)
Map:
HashMap - O(1) // HashMap.HashTrieMap
TreeMap - O(N) // RedBlackTree.count - recursive with stack usage
ListMap - O(N)
来自文档:
为了计算
Stream
的长度,首先必须完全实现它,这可能导致无限系列的完整评估,假设是Stream
所代表的。
Stack#length
复杂性比List#length
复杂度要差得多:它会创建N
个新对象来迭代Stack
。
BitSet
用于小整数的集合。
BitSet#size
的复杂性取决于最大元素,而不是元素数量。这是关于O(Max/64)
。另请参阅BitSet#size implementation。
我不确定TreeSet
和TreeMap
复杂度,它看起来像堆栈使用递归(不是尾递归)。请参阅RedBlackTree.count implementation。
答案 1 :(得分:1)
Vector
具有常量size
操作Array
有一个size
操作ListBuffer
和ArrayBuffer
都有size
次操作。