本文主要是介绍98. 面向对象的LotusScript(十七)之LinkedCollection,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
面向对象编程经常会用到作为容器的对象,使用LotusScript时因为基本上是和单一的数据对象NotesDocument打交道,用作容器的就是数据库的视图或包含搜索结果的文档集合。但有时也需要某个通用容器来容纳其他自定义的对象。此时一般可考虑用数组,或者像20. 面向对象的LotusScript(三)之NArray介绍的编写一个基于动态数组的容器类。本文给出另一种容器的实现方式,对外的接口也像NArray一样是一个Collection,内部实现则不依赖于数组,而采用链接的节点。由于LotusScript的数组在包含数组时有层次上的限制,所以本容器类在理论上适用范围更广(虽然极少遇到这样极端的情况,基本上还是作为一个普通的容器类使用)。
'先定义一个用作节点的类
Class LinkedNodePublic PreviousNode As LinkedNodePublic NextNode As LinkedNodePublic Value As Variant'prevNode As LinkedNode, nextNode As LinkedNodeSub New(value As Variant)Call SetValue(me.Value, value)End Sub Sub Append(nnode As LinkedNode)Set me.NextNode=nnodeSet nnode.PreviousNode=MeEnd Sub Function IsEqualTo(node As LinkedNode) As BooleanIf node Is Me ThenIsEqualTo=TrueExit Function End IfIf Equals(node.Value, me.Value) ThenIsEqualTo=TrueElseIsEqualTo=False End IfEnd Function
End Class
'接下来是链接集合类
Class LinkedCollectionPrivate msize As IntegerPrivate anchor As LinkedNodePrivate current As LinkedNode'Public Parent As LinkedCollectionSub New()Set anchor=New LinkedNode(Null)Call anchor.Append(anchor)Call Me.Reset()'Set anchor.PreviousNode=anchor'Set anchor.NextNode=anchorEnd SubProperty Get Size As IntegerSize=msizeEnd PropertyFunction FirstNode() As LinkedNodeDim node As LinkedNodeSet node=anchor.NextNodeIf Not anchor.NextNode Is anchor ThenSet FirstNode=anchor.NextNodeEnd IfEnd FunctionFunction LastNode() As LinkedNodeIf Not anchor.PreviousNode Is anchor ThenSet LastNode = anchor.PreviousNodeEnd If End FunctionSub Reset()Set current=anchorEnd SubFunction HasNext() As BooleanHasNext=Not current.NextNode Is anchorEnd FunctionFunction Next() As LinkedNodeSet current=current.NextNodeIf current Is anchor ThenSet Me.Next=Nothing 'Error 4000, "LinkedList: no such element."End IfSet Me.Next=currentEnd Function Function Add(value As Variant)Dim node As New LinkedNode(value)Call anchor.PreviousNode.Append(node)Call node.Append(anchor)msize=msize+1End FunctionFunction Contains(value As Variant) As BooleanIf Find(value) Is Nothing ThenContains=FalseElseContains=True End IfEnd FunctionFunction ContainsNode(node As LinkedNode) As BooleanCall Me.Reset()While HasNext()If Me.Next() Is node ThenContainsNode=True End IfWend ContainsNode=False End FunctionFunction Remove(value As Variant) As BooleanDim node As LinkedNodeSet node=Find(value)If node Is Nothing ThenMe.Remove=False ElseCall DirectRemoveNode(node)Me.Remove=True End If End FunctionFunction RemoveCurrent() As BooleanIf current Is anchor ThenRemoveCurrent=FalseElseCall DirectRemoveNode(current)Set current=current.PreviousNodeEnd IfEnd FunctionPrivate Sub DirectRemoveNode(node As LinkedNode)Call node.PreviousNode.Append(node.NextNode)msize=msize-1 End SubFunction Find(value As Variant) As LinkedNodeDim node As LinkedNode Call Me.Reset()While HasNext()Set node=Me.Next()If Equals(value, node.Value) ThenSet Find=nodeExit Function End IfWend End FunctionFunction Clone() As LinkedCollectionDim col As New LinkedCollection'Dim node As LinkedNodeCall Me.Reset()While HasNext()Call col.Add(Me.Next().Value) Wend'Set col.Parent=me.ParentSet Clone=colEnd FunctionFunction AddArray(array As Variant)ForAll e In arrayAdd(e)End ForAllEnd Function'The node value of two LinkedCollection instances must not point to their 'ancestors of LinkedCollection in the same hierarchy level. Or an infinite loop'will occur during comparing these two instances. Function IsEqualTo(lc As Variant) As BooleanIf Not InstanceOf(lc, TypeName(Me)) ThenIsEqualTo=FalseExit Function End IfIf lc Is Me ThenIsEqualTo=TrueExit Function End IfIf lc.Size >< me.Size ThenIsEqualTo=FalseExit Function End IfDim c1 As LinkedCollection, c2 As LinkedCollection Set 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=FalseExit Function End IfWendIsEqualTo=True End Function
End Class
该集合类的方法从名称上都可以看出含义,包括添加单个值、添加数组、克隆、判断是否包含某值、查找包含某值的节点、返回首个节点、判断是否还有下个节点、用于比较等值的IsEqualTo、返回末个节点、返回下个节点、删除包含某值的节点、删除当前节点、重置内部指针以及返回集合包含节点的数量。
其中Reset、HasNext和Next三个方法合起来用于遍历集合内所有的节点:
Call col.Reset()
If col.HasNext() ThenSet node=col.Next()value=node.Value '或Set value=node.Value
End If
注意LinkedCollection和LinkedNode类都有一个IsEqualTo方法,可以被87. 再谈变体型Variant里介绍的计算相等性的Equals函数调用。
另外在LinkedCollection的链接实现方式上,采用了一个特殊的初始节点作为“锚”,使得对于从零到任意多个节点,在返回首位节点、添加节点、判断是否有下个节点等操作时,都有一致简单的逻辑。
这篇关于98. 面向对象的LotusScript(十七)之LinkedCollection的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!