98. 面向对象的LotusScript(十七)之LinkedCollection

面向对象编程经常会用到作为容器的对象,使用LotusScript时因为基本上是和单一的数据对象NotesDocument打交道,用作容器的就是数据库的视图或包含搜索结果的文档集合。但有时也需要某个通用容器来容纳其他自定义的对象。此时一般可考虑用数组,或者像20. 面向对象的LotusScript(三)之NArray介绍的编写一个基于动态数组的容器类。本文给出另一种容器的实现方式,对外的接口也像NArray一样是一个Collection,内部实现则不依赖于数组,而采用链接的节点。由于LotusScript的数组在包含数组时有层次上的限制,所以本容器类在理论上适用范围更广(虽然极少遇到这样极端的情况,基本上还是作为一个普通的容器类使用)。

‘先定义一个用作节点的类Class LinkedNodePublic PreviousNode As LinkedNodePublic NextNode As LinkedNodePublic Value As Variant(value As Variant)Call SetValue(me.Value, value)Append(nnode As LinkedNode)Set me.NextNode=nnodeIsEqualTo(node As LinkedNode) As BooleanIsEqualTo=Equals(node.Value, me.Value) ThenIsEqualTo=TrueElseIsEqualTo=LinkedCollectionPrivate msize As IntegerPrivate anchor As LinkedNodePrivate current As LinkedNode()Set anchor=New LinkedNode(Null)Call anchor.Append(anchor)Call Me.Reset()Size As IntegerSize=msizeFirstNode() As LinkedNodeDim node As LinkedNodeSet node=anchor.NextNodeFirstNode=anchor.NextNodeLastNode() As LinkedNodeLastNode = anchor.PreviousNodeReset()Set current=anchorHasNext() As BooleanHasNext=Not current.NextNode Is anchor() As LinkedNodeSet current=current.NextNode..Next=currentAdd(value As Variant)Dim node As New LinkedNode(value)Call anchor.PreviousNode.Append(node)Call node.Append(anchor)msize=msize+Contains(value As Variant) As BooleanContains=FalseElseContains=ContainsNode(node As LinkedNode) As BooleanCall Me.Reset()While HasNext()If Me.Next() Is node ThenContainsNode=ContainsNode=Remove(value As Variant) As BooleanDim node As LinkedNodeSet node=Find(value).Remove=DirectRemoveNode(node)RemoveCurrent() As BooleanIf current Is anchor ThenRemoveCurrent=DirectRemoveNode(current)Set current=current.PreviousNodeDirectRemoveNode(node As LinkedNode)Call node.PreviousNode.Append(node.NextNode)msize=msize-Find(value As Variant) As LinkedNodeDim node As LinkedNodeCall Me.Reset()While HasNext()Set node=Me.Next()If Equals(value, node.Value) ThenSet Find=nodeClone() As LinkedCollectionDim col As New LinkedCollection.Reset()While HasNext()Call col.Add(Me.Next().Value)Clone=colAddArray(array As Variant)ForAll e In arrayAdd(e)End ForAllIsEqualTo(lc As Variant) As BooleanIf Not InstanceOf(lc, TypeName(Me)) ThenIsEqualTo=lc IsEqualTo=lc.Size >< me.Size ThenIsEqualTo=c1 As LinkedCollection, c2 As LinkedCollectionSet c1=Me.Clone()Set c2=lc.Clone()Call c1.Reset()Call c2.Reset()While c1.HasNext()If c2.Remove(c1.Next().Value) ThenCall c1.RemoveCurrent()ElseIsEqualTo=IsEqualTo=

该集合类的方法从名称上都可以看出含义,包括添加单个值、添加数组、克隆、判断是否包含某值、查找包含某值的节点、返回首个节点、判断是否还有下个节点、用于比较等值的IsEqualTo、返回末个节点、返回下个节点、删除包含某值的节点、删除当前节点、重置内部指针以及返回集合包含节点的数量。 其中Reset、HasNext和Next三个方法合起来用于遍历集合内所有的节点:

Call col.Reset()If col.HasNext() ThenSet node=col.Next()value=node.Value

注意LinkedCollection和LinkedNode类都有一个IsEqualTo方法,可以被87. 再谈变体型Variant里介绍的计算相等性的Equals函数调用。 另外在LinkedCollection的链接实现方式上,,采用了一个特殊的初始节点作为“锚”,使得对于从零到任意多个节点,在返回首位节点、添加节点、判断是否有下个节点等操作时,都有一致简单的逻辑。

如果心胸不似海,又怎能有海一样的事业。

98. 面向对象的LotusScript(十七)之LinkedCollection

相关文章:

你感兴趣的文章:

标签云: