首页 / 知识
关于集合:.NET中Queue < T >的大小限制?
2023-04-11 14:51:00

Limit size of Queue
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class LimitedQueue< T > : Queue< T > { public int Limit { get; set; } public LimitedQueue(int limit) : base(limit) { Limit = limit; } public new void Enqueue(T item) { while (Count >= Limit) { Dequeue(); } base.Enqueue(item); } } |
我建议您拉起C5库。与SCG(System.Collections.Generic)不同,C5被编程为接口并被设计为子类。大多数公共方法是虚拟的,没有一个类是密封的。这样,您将不必使用那个讨厌的" new"关键字,如果将您的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | using C5; public class LimitedQueue< T > : CircularQueue< T > { public int Limit { get; set; } public LimitedQueue(int limit) : base(limit) { this.Limit = limit; } public override void Push(T item) { CheckLimit(false); base.Push(item); } public override void Enqueue(T item) { CheckLimit(true); base.Enqueue(item); } protected virtual void CheckLimit(bool enqueue) { while (this.Count >= this.Limit) { if (enqueue) { this.Dequeue(); } else { this.Pop(); } } } } |
我认为这段代码应该完全符合您的期望。
您应该创建自己的类,环形缓冲区可能会满足您的需求。
.NET中的数据结构允许您指定容量(数组除外),该数据结构用于构建用于保存内部数据的内部数据结构。
例如,对于列表,容量用于确定内部阵列的大小。当您开始向列表中添加元素时,它将开始从索引0开始填充该数组,当其达到您的容量时,它将容量增加到新的更高容量,并继续进行填充。
好吧,我希望这个课程对您有帮助:
在内部,循环FIFO缓冲区使用具有指定大小的Queue < T >。
一旦达到缓冲区的大小,它将用新的替换旧的项目。
注意:您不能随机删除项目。我将方法Remove(T item)设置为返回false。
如果您愿意,可以修改以随机删除项目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | public class CircularFIFO< T > : ICollection< T > , IDisposable { public Queue< T > CircularBuffer; /// <summary> /// The default initial capacity. /// </summary> private int capacity = 32; /// <summary> /// Gets the actual capacity of the FIFO. /// </summary> public int Capacity { get { return capacity; } } /// <summary> /// Initialize a new instance of FIFO class that is empty and has the default initial capacity. /// </summary> public CircularFIFO() { CircularBuffer = new Queue< T >(); } /// <summary> /// Initialize a new instance of FIFO class that is empty and has the specified initial capacity. /// </summary> /// <param name="size"> Initial capacity of the FIFO. </param> public CircularFIFO(int size) { capacity = size; CircularBuffer = new Queue< T >(capacity); } /// <summary> /// Adds an item to the end of the FIFO. /// </summary> /// <param name="item"> The item to add to the end of the FIFO. </param> public void Add(T item) { if (this.Count >= this.Capacity) Remove(); CircularBuffer.Enqueue(item); } /// <summary> /// Adds array of items to the end of the FIFO. /// </summary> /// <param name="item"> The array of items to add to the end of the FIFO. </param> public void Add(T[] item) { int enqueuedSize = 0; int remainEnqueueSize = this.Capacity - this.Count; for (; (enqueuedSize < item.Length && enqueuedSize < remainEnqueueSize); enqueuedSize++) CircularBuffer.Enqueue(item[enqueuedSize]); if ((item.Length - enqueuedSize) != 0) { Remove((item.Length - enqueuedSize));//remaining item size for (; enqueuedSize < item.Length; enqueuedSize++) CircularBuffer.Enqueue(item[enqueuedSize]); } } /// <summary> /// Removes and Returns an item from the FIFO. /// </summary> /// <returns> Item removed. </returns> public T Remove() { T removedItem = CircularBuffer.Peek(); CircularBuffer.Dequeue(); return removedItem; } /// <summary> /// Removes and Returns the array of items form the FIFO. /// </summary> /// <param name="size"> The size of item to be removed from the FIFO. </param> /// <returns> Removed array of items </returns> public T[] Remove(int size) { if (size > CircularBuffer.Count) size = CircularBuffer.Count; T[] removedItems = new T[size]; for (int i = 0; i < size; i++) { removedItems[i] = CircularBuffer.Peek(); CircularBuffer.Dequeue(); } return removedItems; } /// <summary> /// Returns the item at the beginning of the FIFO with out removing it. /// </summary> /// <returns> Item Peeked. </returns> public T Peek() { return CircularBuffer.Peek(); } /// <summary> /// Returns the array of item at the beginning of the FIFO with out removing it. /// </summary> /// <param name="size"> The size of the array items. </param> /// <returns> Array of peeked items. </returns> public T[] Peek(int size) { T[] arrayItems = new T[CircularBuffer.Count]; CircularBuffer.CopyTo(arrayItems, 0); if (size > CircularBuffer.Count) size = CircularBuffer.Count; T[] peekedItems = new T[size]; Array.Copy(arrayItems, 0, peekedItems, 0, size); return peekedItems; } /// <summary> /// Gets the actual number of items presented in the FIFO. /// </summary> public int Count { get { return CircularBuffer.Count; } } /// <summary> /// Removes all the contents of the FIFO. /// </summary> public void Clear() { CircularBuffer.Clear(); } /// <summary> /// Resets and Initialize the instance of FIFO class that is empty and has the default initial capacity. /// </summary> public void Reset() { Dispose(); CircularBuffer = new Queue< T >(capacity); } #region ICollection< T > Members /// <summary> /// Determines whether an element is in the FIFO. /// </summary> /// <param name="item"> The item to locate in the FIFO. </param> /// <returns></returns> public bool Contains(T item) { return CircularBuffer.Contains(item); } /// <summary> /// Copies the FIFO elements to an existing one-dimensional array. /// </summary> /// <param name="array"> The one-dimensional array that have at list a size of the FIFO </param> /// <param name="arrayIndex"></param> public void CopyTo(T[] array, int arrayIndex) { if (array.Length >= CircularBuffer.Count) CircularBuffer.CopyTo(array, 0); } public bool IsReadOnly { get { return false; } } public bool Remove(T item) { return false; } #endregion #region IEnumerable< T > Members public IEnumerator< T > GetEnumerator() { return CircularBuffer.GetEnumerator(); } #endregion #region IEnumerable Members IEnumerator IEnumerable.GetEnumerator() { return CircularBuffer.GetEnumerator(); } #endregion #region IDisposable Members /// <summary> /// Releases all the resource used by the FIFO. /// </summary> public void Dispose() { CircularBuffer.Clear(); CircularBuffer = null; GC.Collect(); } #endregion } |
您为什么不只使用大小为2的数组?队列应该能够动态增长和收缩。
或围绕一个
并发解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class LimitedConcurrentQueue<ELEMENT> : ConcurrentQueue<ELEMENT> { public readonly int Limit; public LimitedConcurrentQueue(int limit) { Limit = limit; } public new void Enqueue(ELEMENT element) { base.Enqueue(element); if (Count > Limit) { TryDequeue(out ELEMENT discard); } } } |
注意:由于
如果对任何人有用,我就做了一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public class LimitedStack< T > { public readonly int Limit; private readonly List< T > _stack; public LimitedStack(int limit = 32) { Limit = limit; _stack = new List< T >(limit); } public void Push(T item) { if (_stack.Count == Limit) _stack.RemoveAt(0); _stack.Add(item); } public T Peek() { return _stack[_stack.Count - 1]; } public void Pop() { _stack.RemoveAt(_stack.Count - 1); } public int Count { get { return _stack.Count; } } } |
太大时,它将删除最旧的项目(堆栈底部)。
(此问题是Google针对" C#限制堆栈大小"的最高结果)
最新内容
相关内容
python如何确定是否为可迭代对象
python如何确定是否为可迭代对象,培训,元素,索引,对象,整数,字典,函数,类型,下标,模块,迭代可以理解为,任意的集合使用for循环遍历python中,迭python怎么判断某一对象是否为字典
python怎么判断某一对象是否为字典,培训,名称,代码,情况,类型,实例,元素,字典,函数,对象,我们经常需要在Python代码中确定某个实例是什么类型python如何查看对象属性
python如何查看对象属性,培训,网络,系统,函数,对象,属性,变量,示例,实例,模块,在Python语言中,有些库在使用时,在网络上找到的文档不全,这就需要python计算集合交集的符号
python计算集合交集的符号,培训,符号,参数,更多,语法,实例,元素,以上,两个,教程,python计算集合交集的符号说明1、可以使用&符号来计算两个或python集合的并集操作
python集合的并集操作,培训,操作,参数,更多,语法,符号,实例,元素,以上,两个,python集合的并集操作说明1、可以使用|符号来计算两个或更多集合python集合的差集如何计算
python集合的差集如何计算,培训,参数,更多,语法,符号,实例,元素,以上,两个,方法,python集合的差集如何计算说明1、可以使用-符号来计算两个或python集合魔法函数有哪些
python集合魔法函数有哪些,培训,方法,函数,对象,魔法,字典,实例,以上,教程,更多,python集合魔法函数有哪些说明1、_len_调用len()方法时,就是关于c#:找不到导入的项目“ C:Microso
关于c#:找不到导入的项目“ C:Microsoft.CSharp.targets”,关于c#:找不到导入的项目“ C:Microsoft.CSharp.targets”,错误,项目,尝试,收关于语言不可知:如何将代码贡献回开
关于语言不可知:如何将代码贡献回开源项目?,关于语言不可知:如何将代码贡献回开源项目?,开源项目,如果您,我会,做什么,How to contribute关于不可知的语言:项目中的国际化
关于不可知的语言:项目中的国际化,关于不可知的语言:项目中的国际化,开发人员,知识,国际化,我对,Internationalization in your projec向Window对象添加事件句柄
向Window对象添加事件句柄,向,Window,对象,添加,事件,句柄,向,Window,对象,, 向Window对象添加事件句柄 addEventListener()js-数字可以私有数据进行初始化
js-数字可以私有数据进行初始化,js-,数字,可以,是,或者,对象,数字,可以,是,,数字可以是数字或者对象数字可以私有数据进行初始化,就