.NET似乎有很多数据结构和集合类型。它是否具有具有最大大小且没有重复项的先进先出集合,或类似于此的内容?
一个示例用法可能是存储5个最近打开的文件。如果添加第6个对象,则弹出最不常用的对象以将大小保持为5。
.NET似乎有很多数据结构和集合类型。它是否具有具有最大大小且没有重复项的先进先出集合,或类似于此的内容?
一个示例用法可能是存储5个最近打开的文件。如果添加第6个对象,则弹出最不常用的对象以将大小保持为5。
ICollection<T>
的 QueueSet
。它可以是一个包含一个集合作为后备存储的包装类。可以按照以下方式实现:class QueueSet<T> : ICollection<T>
{
List<T> queue=new List<T>();
int maximumSize;
public QueueSet(int maximumSize){
if(maximumSize<0)
throw new ArgumentOutOfRangeException("maximumSize");
this.maximumSize=maximumSize;
}
public T Dequeue(){
if(queue.Count>0){
T value=queue[0];
queue.RemoveAt(0);
return value;
}
return default(T);
}
public T Peek(){
if(queue.Count>0){
return queue[0];
}
return default(T);
}
public void Enqueue(T item){
if(queue.Contains(item)){
queue.Remove(item);
}
queue.Add(item);
while(queue.Count>maximumSize){
Dequeue();
}
}
public int Count {
get {
return queue.Count;
}
}
public bool IsReadOnly {
get {
return false;
}
}
public void Add(T item)
{
Enqueue(item);
}
public void Clear()
{
queue.Clear();
}
public bool Contains(T item)
{
return queue.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
foreach(T value in queue){
if(arrayIndex>=array.Length)break;
if(arrayIndex>=0){
array[arrayIndex]=value;
}
arrayIndex++;
}
}
public bool Remove(T item)
{
if(Object.Equals(item,Peek())){
Dequeue();
return true;
} else {
return false;
}
}
public IEnumerator<T> GetEnumerator()
{
return queue.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return queue.GetEnumerator();
}
}
public class LimitedQueue : Queue
{
public override void Enqueue(object obj)
{
if (this.Count > 5)
throw new Exception();
if(this.Contains(obj))
throw new Exception();
base.Enqueue(obj);
}
}
public class QueueWrapper<T>
{
private Queue<T> _queue;
public void Enqueue(T item)
{
if (_queue.Count > 5)
throw new Exception();
if(this.Contains(item))
throw new Exception();
_queue.Enqueue(item);
}
//Any other methods you might want to use would also need to be exposed similarly
}
Queue<T>
不起作用(因为我已经强调过的原因)。你真的应该使用Queue<T>
,但我想这可能有潜力。 - Matthew ScharleyHashQueue<T>
,哈希队列集合。using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Security.Permissions;
namespace ConsoleApplication
{
internal class Program
{
[Serializable]
private class HashQueue<T> : ISerializable, IDeserializationCallback, ISet<T>, ICollection<T>, IEnumerable<T>, IEnumerable
{
private int _maxCount;
private Queue<T> _queue = new Queue<T>();
private HashSet<T> _set = new HashSet<T>();
public HashQueue(int maxCount = 0)
{
if (maxCount < 0) throw new ArgumentOutOfRangeException("maxCount");
_maxCount = maxCount;
}
public bool Add(T item)
{
lock (this)
{
if (_queue.Count == _maxCount)
{
_set.Remove(_queue.Dequeue());
}
if (_set.Add(item))
{
_queue.Enqueue(item);
return true;
}
return false;
}
}
public bool Remove(T item)
{
lock (this)
{
if (object.ReferenceEquals(_queue.Peek(), item))
{
return _set.Remove(_queue.Dequeue());
}
return false;
}
}
public void Clear()
{
lock (this)
{
_set.Clear();
_queue.Clear();
}
}
public bool Contains(T item)
{
lock (this)
{
return _set.Contains(item);
}
}
public void CopyTo(T[] array, int arrayIndex)
{
lock (this)
{
_queue.CopyTo(array, arrayIndex);
}
}
public int Count
{
get
{
lock (this)
{
return _queue.Count;
}
}
}
public bool IsReadOnly
{
get
{
return false;
}
}
public void ProcessItems(Action<T> action)
{
lock (this)
{
foreach (T item in _queue)
{
action(item);
}
}
}
void ICollection<T>.Add(T item)
{
lock (this)
{
if (_queue.Count == _maxCount)
{
_set.Remove(_queue.Dequeue());
}
if (!_set.Add(item))
{
throw new ArgumentOutOfRangeException("item");
}
_queue.Enqueue(item);
}
}
public IEnumerator<T> GetEnumerator()
{
lock (this)
{
return _queue.GetEnumerator();
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
lock (this)
{
return (IEnumerator)GetEnumerator();
}
}
public void OnDeserialization(object sender)
{
lock (this)
{
_set.OnDeserialization(sender);
}
}
private void RebuildQuery()
{
_queue.Clear();
foreach (T item in _set)
{
_queue.Enqueue(item);
}
}
public void ExceptWith(IEnumerable<T> other)
{
lock (this)
{
_set.ExceptWith(other);
RebuildQuery();
}
}
public void IntersectWith(IEnumerable<T> other)
{
lock (this)
{
_set.IntersectWith(other);
RebuildQuery();
}
}
public bool IsProperSubsetOf(IEnumerable<T> other)
{
lock (this)
{
return _set.IsProperSubsetOf(other);
}
}
public bool IsProperSupersetOf(IEnumerable<T> other)
{
lock (this)
{
return _set.IsProperSupersetOf(other);
}
}
public bool IsSubsetOf(IEnumerable<T> other)
{
lock (this)
{
return _set.IsSubsetOf(other);
}
}
public bool IsSupersetOf(IEnumerable<T> other)
{
lock (this)
{
return _set.IsSupersetOf(other);
}
}
public bool Overlaps(IEnumerable<T> other)
{
lock (this)
{
return _set.Overlaps(other);
}
}
public bool SetEquals(IEnumerable<T> other)
{
lock (this)
{
return _set.SetEquals(other);
}
}
public void SymmetricExceptWith(IEnumerable<T> other)
{
lock (this)
{
_set.SymmetricExceptWith(other);
RebuildQuery();
}
}
public void UnionWith(IEnumerable<T> other)
{
lock (this)
{
_set.UnionWith(other);
RebuildQuery();
}
}
[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
_set.GetObjectData(info, context);
}
}
private static void Main(string[] args)
{
HashQueue<int> queue = new HashQueue<int>(5);
queue.Add(1);
queue.Add(2);
queue.Add(3);
queue.Add(4);
queue.Add(5);
queue.Add(6);
queue.ProcessItems((i) => Console.Write(i));
//foreach (int i in queue)
//{
// Console.Write("{0}", i);
//}
}
}
}
看一下这个:如何在.NET中限制Queue<T>的大小?
你基本上需要一个Queue
,如果你设法限制它的大小并使其“索引化”或“唯一化”,那么就没问题了 :)
我相信围绕一个Dictionary
的一些逻辑也可以解决问题,你将存储什么数据类型?字符串吗?