一个先进先出、限长数组的流水链表 RunnelList
在.NET中可以用 Queue 类型 来定义一个先进先出的无限制的数据链表,但Queue无法限制内部元素长度,它会在数据超过当前长度时自动增长,并且其内部可调用的方法也比较少,不够强大和灵活。
我写这个类型的目的除了补充Queue的缺陷之外,主要是为了限定数据的长度而设计的。
在某些坏境场景下,可能需要一个先进先出的缓存,或者如同一个流水线一般,较旧的数据需要随着时间的推移而舍去,腾出宝贵的内存空间用以存储新的数据,这时候,RunnelList就可以起到大作用了。
我写这个类型的目的除了补充Queue的缺陷之外,主要是为了限定数据的长度而设计的。
在某些坏境场景下,可能需要一个先进先出的缓存,或者如同一个流水线一般,较旧的数据需要随着时间的推移而舍去,腾出宝贵的内存空间用以存储新的数据,这时候,RunnelList就可以起到大作用了。
''' <summary>流水链</summary>
''' <typeparam name="T"></typeparam>
Public Class RunnelList(Of T)
Implements IEnumerable
Dim _count As Integer
Dim alist As New List(Of T)
''' <summary>
''' 创建一个流水链
''' </summary>
''' <param name="count">流水链的长度</param>
''' <remarks></remarks>
Sub New(ByVal count As Integer, ByVal ParamArray items As T())
If count < 1 Then
Throw New ArgumentException("数组长度至少为1")
End If
If items IsNot Nothing AndAlso items.Length > count Then
Throw New ArgumentException("数组长度溢出")
End If
_count = count
alist.AddRange(items)
End Sub
''' <summary>增加一个数据到链中</summary>
''' <param name="item"></param>
Public Sub Add(ByVal item As T)
If alist.Count > _count Then
alist.RemoveRange(0, alist.Count - _count)
ElseIf alist.Count = _count Then
alist.RemoveAt(0)
End If
alist.Add(item)
End Sub
''' <summary>添加一组数据到流水链中</summary>
Public Sub AddRange(ByVal ParamArray items As T())
If items.Length = 0 Then Return
If items.Length > _count Then
Throw New ArgumentException("参数数组长度溢出")
End If
alist.RemoveRange(0, items.Length)
alist.AddRange(items)
End Sub
''' <summary>清除流水链中的全部数据</summary>
Public Sub Clear()
alist.Clear()
End Sub
''' <summary>将数据复制到数组中</summary>
Public Sub CopyTo(ByVal array() As T)
alist.CopyTo(array)
End Sub
Public Sub CopyTo(ByVal array() As T, ByVal arrayIndex As Integer)
alist.CopyTo(array, arrayIndex)
End Sub
Public Sub CopyTo(ByVal index As Integer, ByVal array() As T, ByVal arrayIndex As Integer, ByVal count As Integer)
alist.CopyTo(index, array, arrayIndex, count)
End Sub
''' <summary>检查某元素是否存在</summary>
Public Function Contains(ByVal item As T) As Boolean
Return alist.Contains(item)
End Function
''' <summary>移除指定元素</summary>
Public Function Remove(ByVal item As T) As Boolean
Return alist.Remove(item)
End Function
''' <summary>移除指定位置的元素</summary>
Public Sub RemoveAt(ByVal index As Integer)
alist.RemoveAt(index)
End Sub
''' <summary>移除一段数据</summary>
Public Sub RemoveRange(ByVal index As Integer, ByVal count As Integer)
'If index < 0 OrElse count < 1 Then
' Throw New ArgumentException("参数错误")
'End If
If count - index > _count Then
Throw New ArgumentException("删除的参数长度超过限制")
End If
alist.RemoveRange(index, count)
End Sub
''' <summary>找到元素的位置</summary>
Public Function IndexOf(ByVal item As T) As Integer
Return alist.IndexOf(item)
End Function
''' <summary></summary>
Public Sub Insert(ByVal index As Integer, ByVal item As T)
If index < 0 Then
Throw New ArgumentException("错误的索引位置")
End If
If index >= _count Then
Throw New ArgumentException("索引位置超出流水链长度")
End If
alist.Insert(index, item)
If index = 0 Then
alist.RemoveAt(1)
Else
alist.RemoveAt(0)
End If
End Sub
''' <summary>将元素压入流水链</summary>
Public Sub Push(ByVal item As T)
Add(item)
End Sub
''' <summary>返回第一个有效元素</summary>
Public Function Peek() As T
Return alist(0)
End Function
''' <summary>返回第一个有效元素并删除</summary>
Public Function Pop() As T
Dim o As T = alist(0)
alist.RemoveAt(0)
Return o
End Function
''' <summary>返回流水链的数组</summary>
Public Function ToArray() As T()
Return alist.ToArray
End Function
''' <summary>返回或设置流水链长度</summary>
Public Property Count() As Integer
Get
Return _count
End Get
Set(ByVal value As Integer)
If alist.Count > value Then
' 在这里默认先进的数据更陈旧,将被舍去
alist.RemoveRange(0, alist.Count - value)
End If
_count = value
End Set
End Property
''' <summary>返回当前流水链内数据长度</summary>
Public ReadOnly Property ListCount() As Integer
Get
Return alist.Count
End Get
End Property
''' <summary>直接操作流水链内数据</summary>
Default Public Property Item(ByVal index As Integer) As T
Get
If index < 0 Then
Throw New ArgumentException("错误的索引位置")
End If
If index >= _count Then
Throw New ArgumentException("索引位置超出流水链长度")
End If
Return alist(index)
End Get
Set(ByVal value As T)
If index < 0 Then
Throw New ArgumentException("错误的索引位置")
End If
If index >= _count Then
Throw New ArgumentException("索引位置超出流水链长度")
End If
alist(index) = value
End Set
End Property
Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
Return New RunnelTEnum(Of T)(alist)
End Function
End Class
Public NotInheritable Class RunnelTEnum(Of T)
Implements IEnumerator
Dim alist As List(Of T)
Dim position As Integer = -1
Sub New(ByVal thelist As List(Of T))
alist = thelist
End Sub
Public ReadOnly Property Current() As Object Implements System.Collections.IEnumerator.Current
Get
Return alist(position)
End Get
End Property
Public Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext
position += 1
Return (position < alist.Count)
End Function
Public Sub Reset() Implements System.Collections.IEnumerator.Reset
position = -1
End Sub
End Class
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。