C#的List和DIctionary实现原理(手搓泛型类以及增删查改等功能)
这里写自定义目录标题
- List
- DIctionary
List
MyList类:这是一个泛型类,能够存储任意类型的元素。
_items数组:用于实际存储元素。
_size变量:记录当前列表中的元素数量。
构造函数:初始化数组容量为 4。
Count属性:获取列表中的元素数量。
索引器this[int index]:用于访问列表中的元素。
Add方法:向列表中添加元素,若数组容量不足,会调用EnsureCapacity方法来扩容。
EnsureCapacity方法:确保数组容量足够,若不足则将数组容量扩大为原来的 2 倍。
using System;
// 自定义列表类
public class MyList<T>
{
private T[] _items;
private int _size;
// 构造函数,初始化数组容量
public MyList()
{
_items = new T[4];
_size = 0;
}
// 获取列表中的元素数量
public int Count
{
get { return _size; }
}
// 索引器,用于访问列表中的元素
public T this[int index]
{
get
{
if (index < 0 || index >= _size)
{
throw new IndexOutOfRangeException();
}
return _items[index];
}
set
{
if (index < 0 || index >= _size)
{
throw new IndexOutOfRangeException();
}
_items[index] = value;
}
}
// 向列表中添加元素
public void Add(T item)
{
if (_size == _items.Length)
{
EnsureCapacity(_size + 1);
}
_items[_size++] = item;
}
// 确保数组容量足够
private void EnsureCapacity(int min)
{
if (_items.Length < min)
{
int newCapacity = _items.Length == 0 ? 4 : _items.Length * 2;
if (newCapacity < min)
{
newCapacity = min;
}
Array.Resize(ref _items, newCapacity);
}
}
}
class Program
{
static void Main()
{
// 创建自定义列表实例
MyList<int> myList = new MyList<int>();
// 添加元素
myList.Add(1);
myList.Add(2);
myList.Add(3);
// 访问元素
for (int i = 0; i < myList.Count; i++)
{
Console.WriteLine(myList[i]);
}
}
}
DIctionary
MyDictionary<TKey, TValue>类:这是一个泛型类,可存储任意类型的键值对。
Entry结构体:用于存储单个键值对,包含键的哈希码、键和值。
_entries数组:实际存储键值对的数组。
_count变量:记录当前字典中的键值对数量。
构造函数:初始化数组容量为 InitialCapacity(这里设为 4)。
Count属性:获取字典中的键值对数量。
索引器this[TKey key]:用于根据键获取或设置值。
TryGetValue方法:尝试根据键获取值,如果找到则返回 true 并将值赋给输出参数 value,否则返回 false。
Add方法:向字典中添加键值对,如果键已存在则抛出异常。
Insert方法:插入键值对,会检查键是否已存在,若已存在且 add 参数为 true 则抛出异常,否则更新值。
EnsureCapacity方法:确保数组容量足够,若不足则将数组容量扩大为原来的 2 倍。
using System;
// 自定义字典类
public class MyDictionary<TKey, TValue>
{
private const int InitialCapacity = 4;
private Entry[] _entries;
private int _count;
// 内部存储的键值对结构
private struct Entry
{
public int HashCode;
public TKey Key;
public TValue Value;
}
// 构造函数,初始化数组容量
public MyDictionary()
{
_entries = new Entry[InitialCapacity];
_count = 0;
}
// 获取字典中的键值对数量
public int Count
{
get { return _count; }
}
// 索引器,用于根据键获取或设置值
public TValue this[TKey key]
{
get
{
if (TryGetValue(key, out TValue value))
{
return value;
}
throw new KeyNotFoundException();
}
set
{
Insert(key, value, false);
}
}
// 尝试根据键获取值
public bool TryGetValue(TKey key, out TValue value)
{
for (int i = 0; i < _count; i++)
{
if (Equals(_entries[i].Key, key))
{
value = _entries[i].Value;
return true;
}
}
value = default(TValue);
return false;
}
// 添加键值对
public void Add(TKey key, TValue value)
{
Insert(key, value, true);
}
// 插入键值对
private void Insert(TKey key, TValue value, bool add)
{
if (_count == _entries.Length)
{
EnsureCapacity(_count + 1);
}
int hashCode = key.GetHashCode();
for (int i = 0; i < _count; i++)
{
if (_entries[i].HashCode == hashCode && Equals(_entries[i].Key, key))
{
if (add)
{
throw new ArgumentException("An item with the same key has already been added.");
}
_entries[i].Value = value;
return;
}
}
_entries[_count].HashCode = hashCode;
_entries[_count].Key = key;
_entries[_count].Value = value;
_count++;
}
// 确保数组容量足够
private void EnsureCapacity(int min)
{
if (_entries.Length < min)
{
int newCapacity = _entries.Length == 0 ? InitialCapacity : _entries.Length * 2;
if (newCapacity < min)
{
newCapacity = min;
}
Array.Resize(ref _entries, newCapacity);
}
}
}
class Program
{
static void Main()
{
// 创建自定义字典实例
MyDictionary<string, int> myDictionary = new MyDictionary<string, int>();
// 添加键值对
myDictionary.Add("apple", 1);
myDictionary.Add("banana", 2);
myDictionary.Add("cherry", 3);
// 根据键获取值
int value;
if (myDictionary.TryGetValue("banana", out value))
{
Console.WriteLine($"The value of 'banana' is: {value}");
}
// 使用索引器设置值
myDictionary["apple"] = 5;
Console.WriteLine($"The new value of 'apple' is: {myDictionary["apple"]}");
}
}