目前我的代码中有以下列表。
private List<myClass> mylist;
我可以用
替换它吗?private LinkedList<myClass> mylist;
目标是当mylist的大小扩展到一定大小(比方说10)时,我从列表中删除最旧的条目并添加最新的条目,依此类推。显然LinkedList
有以下我可以使用的方法(它们不在列表中)
mylist.RemoveFirst();
mylist.AddLast(..);
所以我的问题是,如果我从List
更改为LinkedList
,是否会丢失任何功能?我的意思是我的代码中依赖于List的其他东西会受到影响,或者就像这样你用List做什么,你也可以用LInkedList做到这一点?
其次,或者没有必要改为LinkedList
。我的目标是实现我能用List吗?
(如果我使用List
来实现我的目标
if (mylist.Count >= maxNumEntries)
{
list.RemoveAt(0);
}
list.Add(..);
由于
答案 0 :(得分:1)
我的建议是,无需将List
更改为LinkedList
。它可能会也可能不会产生混淆,具体取决于您的代码。而且,你可以很容易地使用LINQ来制作这些简单的方法
我举一个下面这种方法的例子: -
您可以自定义RemoveFirst方法: -
List<T> RemoveFirst(List<T> paramList)
{
List<T> tempList = paramList.Skip(1).ToList() ;
return tempList ;
}
同样,您可以使用其他方法来操纵List<T>
。
用法
List<int> myList = new List<int> () ;
// add some items to list
// now remove the first item.
myList = RemoveFirst(myList) ;
选择DataStructure
List<T>
和LinkedList<T>
不仅在它们提供的自定义方法中有所不同,而且在实现方面也有所不同
例如
与LinkedList<T>
相比,List<T>
提供了对元素的较慢访问权限
我相信LinkedList<T>
也有许多优势,但优秀的程序员会根据他们提供的属性选择数据结构。
在您的情况下,循环队列也很有用。
因此,请选择数据结构,而不是基于它们提供的方法,而是选择您认为对您的应用程序非常重要的属性。
答案 1 :(得分:0)
您似乎想要一个循环缓冲区(也称为环形缓冲区)。
您可能最好只编写一个自定义类来实现它,例如:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
namespace Demo
{
public class CircularBuffer<T>: IEnumerable<T>
{
/// <summary>Constructor.</summary>
/// <param name="capacity">The maximum capacity of the buffer.</param>
public CircularBuffer(int capacity)
{
// The reason for this +1 is to simplify the logic - we can use "front == back" to indicate an empty buffer.
_buffer = new T[capacity+1];
}
/// <summary>The buffer capacity.</summary>
public int Capacity
{
get
{
return _buffer.Length - 1;
}
}
/// <summary>The number of elements currently stored in the buffer.</summary>
public int Count
{
get
{
int result = _back - _front;
if (result < 0)
result += _buffer.Length;
return result;
}
}
/// <summary>Is the buffer empty?</summary>
public bool IsEmpty
{
get
{
return this.Count == 0;
}
}
/// <summary>Is the buffer full? (i.e. has it reached its capacity?)</summary>
public bool IsFull
{
get
{
return nextSlot(_back) == _front;
}
}
/// <summary>Empties the buffer.</summary>
public void Empty()
{
_front = _back = 0;
Array.Clear(_buffer, 0, _buffer.Length); // Destroy any old references so they can be GCed.
}
/// <summary>Add an element to the buffer, overwriting the oldest element if the buffer is full.</summary>
/// <param name="newItem">The element to add.</param>
public void Add(T newItem)
{
_buffer[_back] = newItem;
_back = nextSlot(_back);
if (_back == _front) // Buffer is full?
{
_front = nextSlot(_front); // Bump the front, overwriting the current front.
_buffer[_back] = default(T); // Remove the old front value.
}
}
/// <summary>
/// The typesafe enumerator. Elements are returned in oldest to newest order.
/// This is not threadsafe, so if you are enumerating the buffer while another thread is changing it you will run
/// into threading problems. Therefore you must use your own locking scheme to avoid the problem.
/// </summary>
public IEnumerator<T> GetEnumerator()
{
for (int i = _front; i != _back; i = nextSlot(i))
yield return _buffer[i];
}
/// <summary>The non-typesafe enumerator.</summary>
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator(); // Implement in terms of the typesafe enumerator.
}
/// <summary>Calculates the index of the slot following the specified one, wrapping if necessary.</summary>
private int nextSlot(int slot)
{
return (slot + 1) % _buffer.Length;
}
/// <summary>
/// The index of the element at the front of the buffer.
/// If this equals _back, the buffer is empty.
/// </summary>
private int _front;
/// <summary>
/// The index of the first element BEYOND the last used element of the buffer.
/// Therefore this indicates where the next added element will go.
/// </summary>
private int _back;
/// <summary>The underlying buffer. This has a length one greater than the actual capacity.</summary>
private readonly T[] _buffer;
}
internal class Program
{
private void run()
{
CircularBuffer<int> buffer = new CircularBuffer<int>(10);
for (int i = 0; i < 20; ++i)
buffer.Add(i);
foreach (int n in buffer)
Console.WriteLine(n); // Prints 10..19
}
private static void Main()
{
new Program().run();
}
}
}