在C#中,是否有一个队列,它在其生命周期内只能容纳一个对象?

7 浏览
0 Comments

在C#中,是否有一个队列,它在其生命周期内只能容纳一个对象?

我需要一个特殊类型的队列数据结构。如果我的队列实例中包含了一个对象X,那么在该实例中就不应该再次将X入队。如果使用X调用入队方法,它应该什么都不做,就像向HashSet添加重复值的尝试一样。

使用示例:

MyQueue queue = new MyQueue();
queue.Enqueue(5);
queue.Enqueue(17);
queue.Enqueue(28);
queue.Enqueue(17);
int firstNumber = queue.Dequeue();
queue.Enqueue(5);
queue.Enqueue(3);
List queueContents = queue.ToList(); //这个列表应该包含{17, 28, 3}

我在MSDN上查了一下,但没有找到这样的类。它存在吗,还是我需要自己实现?我想我也可以使用其他数据结构,但访问总是FIFO,所以我认为队列会是最有效的。此外,我不知道任何其他提供“实例生命周期内唯一性”的结构。

0
0 Comments

在C#中,是否有一个队列只能在其生命周期中保留一个对象?

问题的出现原因:

该问题的出现是因为在C#中的队列(Queue)类没有提供一种机制来确保队列中的对象只能在其生命周期中出现一次。在某些情况下,我们可能希望队列中的对象是唯一的,即每个对象只能添加一次,而不允许重复添加。

解决方法:

为了解决这个问题,可以实现一个“UniqueQueue”类,该类继承自“Queue”类,并在其基础上添加一些额外的功能。这个“UniqueQueue”类使用了一个名为“alreadyAdded”的哈希集合来存储已经添加过的对象,以确保每个对象只能添加一次。

以下是“UniqueQueue”类的实现代码:

sealed class UniqueQueue : IEnumerable, ICollection, IEnumerable
{
    private readonly Queue queue;
    private readonly HashSet alreadyAdded;
    
    public UniqueQueue(IEqualityComparer comparer)
    {
        queue = new Queue();
        alreadyAdded = new HashSet(comparer);
    }
    
    public UniqueQueue(IEnumerable collection, IEqualityComparer comparer)
    {
        var localCopy = collection.ToList();
        queue = new Queue(localCopy);
        alreadyAdded = new HashSet(localCopy, comparer);
    }
    
    public UniqueQueue(int capacity, IEqualityComparer comparer)
    {
        queue = new Queue(capacity);
        alreadyAdded = new HashSet(comparer);
    }
    
    public UniqueQueue() : this((IEqualityComparer) null) { }
    
    public UniqueQueue(IEnumerable collection) : this(collection, null) { }
    
    public UniqueQueue(int capacity) : this(capacity, null) { }
    
    public bool Enqueue(T item)
    {
        if (!alreadyAdded.Add(item))
            return false;
        queue.Enqueue(item);
        return true;
    }
    
    public int Count
    {
        get { return queue.Count; }
    }
    
    public T Dequeue()
    {
        return queue.Dequeue();
    }
    
    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable)queue).GetEnumerator();
    }
    
    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable)queue).GetEnumerator();
    }
    
    void ICollection.CopyTo(Array array, int index)
    {
        ((ICollection)queue).CopyTo(array, index);
    }
    
    bool ICollection.IsSynchronized
    {
        get { return ((ICollection)queue).IsSynchronized; }
    }
    
    object ICollection.SyncRoot
    {
        get { return ((ICollection)queue).SyncRoot; }
    }
}

上述代码中的“UniqueQueue”类具有与标准队列类相似的接口,例如“IEnumerable”和“ICollection”接口。它还添加了一个名为“Enqueue”的方法,该方法尝试将对象添加到队列中,并返回一个布尔值表示是否成功添加对象。如果对象已经在队列中存在,则添加操作将失败,并返回false。如果对象成功添加到队列中,则返回true。

通过使用这个“UniqueQueue”类,我们可以确保队列中的对象在其生命周期中只能存在一次,避免了重复添加的问题。

在C#中,如果需要一个队列只能在其生命周期中保留一个对象,可以通过实现一个“UniqueQueue”类来解决这个问题。这个类使用了一个哈希集合来存储已经添加过的对象,并在添加对象时进行检查,以确保每个对象只能添加一次。这样,我们就可以确保队列中的对象是唯一的。

0
0 Comments

在C#中,是否有一个队列只能在其生命周期中持有一个对象?

这个问题的出现是因为在C#中并没有提供一个可以在其生命周期中只持有一个对象的队列。因此,我们需要自己实现这个功能。

一种解决方法是在入队时,将元素添加到一个HashSet中。然后,在想要入队时,只需检查HashSet中是否存在该项,如果存在,则不进行入队操作。由于希望在队列的余生中防止入队操作,所以可能不希望从HashSet中移除任何元素。

以下是使用HashSet实现只能持有一个对象的队列的示例代码:

using System;
using System.Collections.Generic;
public class UniqueQueue
{
    private Queue queue;
    private HashSet set;
    public UniqueQueue()
    {
        queue = new Queue();
        set = new HashSet();
    }
    public void Enqueue(T item)
    {
        if (!set.Contains(item))
        {
            set.Add(item);
            queue.Enqueue(item);
        }
    }
    public T Dequeue()
    {
        T item = queue.Dequeue();
        set.Remove(item);
        return item;
    }
    public int Count
    {
        get { return queue.Count; }
    }
}
public class Program
{
    public static void Main(string[] args)
    {
        UniqueQueue queue = new UniqueQueue();
        queue.Enqueue(1);
        queue.Enqueue(2);
        queue.Enqueue(3);
        queue.Enqueue(2);
        queue.Enqueue(4);
        while (queue.Count > 0)
        {
            int item = queue.Dequeue();
            Console.WriteLine(item);
        }
    }
}

在上面的代码中,我们创建了一个名为UniqueQueue的类,它使用了一个Queue和一个HashSet来实现只能持有一个对象的队列。在Enqueue方法中,我们首先检查HashSet中是否已经存在了该项,如果不存在,则将其添加到HashSet和Queue中。在Dequeue方法中,我们从Queue中取出元素,并从HashSet中移除该项。

这样,我们就实现了一个只能在其生命周期中持有一个对象的队列。我们可以根据需要将其用作替代System.Collections.Queue的自定义队列实现。

0
0 Comments

在C#中,是否存在一种队列,它在其生命周期中只能持有一个对象?

这个问题的出现是因为有人想要实现一个队列,但是这个队列只能持有一个对象的实例。解决这个问题的方法是创建一个名为UniqueQueue的类,它继承自Queue类,并使用HashSet来保存已添加的对象。下面是解决方法的代码:

class UniqueQueue
{
    private readonly Queue queue = new Queue();
    private HashSet alreadyAdded = new HashSet();
    public virtual void Enqueue(T item)
    {
        if (alreadyAdded.Add(item)) { queue.Enqueue(item); }
    }
    public int Count { get { return queue.Count; } }
    public virtual T Dequeue()
    {
        T item = queue.Dequeue();
        alreadyAdded.Remove(item);
        return item;
    }
}

这段代码中的大部分内容来自于这个线程。在这段代码中,使用HashSet来存储已添加的对象,而不是使用List。因为HashSet的性能更好。

在这个的问题中,某些情况下了使用HashSet的好处,并且建议将已添加的对象从HashSet中删除。这样可以确保下一次调用Enqueue方法时能正常工作。

总之,通过创建一个继承自Queue类的UniqueQueue类,并使用HashSet来保存已添加的对象,可以实现一个只能持有一个对象的队列。

0