使用Array的一个扩展类,允许Add,Remove,Contains
来源:互联网 发布:杂志虫软件 编辑:程序博客网 时间:2024/05/03 00:58
类代码
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Diagnostics;namespace DevGuideToCollections{ /// <summary> /// Represents a strongly typed array. /// </summary> /// <typeparam name="T">Specifies the type of elements in the array.</typeparam> [DebuggerDisplay("Count={Count}")] [DebuggerTypeProxy(typeof(ArrayDebugView))] public class ArrayEx<T> { const int GROW_BY = 10; // Internal variable for holding the array information T[] m_data; // Contains the number of elements in the array. int m_count; int m_updateCode; /// <summary> /// Initializes a new instance of the ArrayEx(T) class that is empty. /// </summary> public ArrayEx() { Initialize(GROW_BY); } /// <summary> /// Initializes a new instance of the ArrayEx(T) class that contains the items in the array. /// </summary> /// <param name="items">Adds items to the ArrayEx(T).</param> public ArrayEx(IEnumerable<T> items) { Initialize(GROW_BY); foreach (T item in items) { Add(item); } } /// <summary> /// Initializes a new instance of the ArrayEx(T) class that is empty and has the specified initial capacity. /// </summary> /// <param name="capacity">The number of elements that the new array can initially store.</param> public ArrayEx(int capacity) { Initialize(capacity); } void Initialize(int capacity) { m_data = new T[capacity]; } /// <summary> /// States if the ArrayEx(T) is empty. /// </summary> public bool IsEmpty { get { return m_count <= 0; } } /// <summary> /// Gets the number of elements actually contained in the ArrayEx(T). /// </summary> public int Count { get { return m_count; } } /// <summary> /// Gets or sets the size of the internal data array. /// </summary> public int Capacity { get { return m_data.Length; } set { // We do not support truncating the stored array. So throw an exception if the array is less than Count. if (value < Count) { throw new ArgumentOutOfRangeException("value", "The value is less than Count"); } // We do not need to do anything if the newly specified capacity is the same as the old one. if (value == Capacity) { return; } // We will need to create a new array and move all of the values in the old array to the new one T[] tmp = new T[value]; for (int i = 0; i < Count; ++i) { tmp[i] = m_data[i]; } m_data = tmp; ++m_updateCode; } } /// <summary> /// Adds an object to the end of the ArrayEx(T). /// </summary> /// <param name="item">The item to add to the end of the ArrayEx(T).</param> public void Add(T item) { if (m_data.Length <= m_count) { Capacity += GROW_BY; } // We will need to assign the item to the last element and then increment the count variable m_data[m_count++] = item; ++m_updateCode; } /// <summary> /// Checks to see if the item is present in the ArrayEx(T). /// </summary> /// <param name="item">The item to see if the array contains.</param> /// <returns>True if the item is in the array, false if it is not.</returns> public bool Contains(T item) { EqualityComparer<T> comparer = EqualityComparer<T>.Default; for (int i = 0; i < m_count; i++) { if (comparer.Equals(m_data[i], item)) { return true; } } return false; } /// <summary> /// Gets the index of the specified item. /// </summary> /// <param name="item">The item to get the index of.</param> /// <returns>-1 if the item isn't found in the array, the index of the found item otherwise.</returns> public int IndexOf(T item) { return Array.IndexOf<T>(m_data, item, 0, m_count); } /// <summary> /// Clears all values from the ArrayEx(T). /// </summary> public void Clear() { Array.Clear(m_data, 0, m_count); ++m_updateCode; m_count = 0; } /// <summary> /// Removes the first occurrence of the specified item from the ArrayEx(T). /// </summary> /// <param name="item">The item to remove from the ArrayEx(T).</param> /// <returns>True if an item was removed, false otherwise.</returns> public bool Remove(T item) { return Remove(item, false); } /// <summary> /// Removes the first or all occurrences of the specified item from the ArrayEx(T). /// </summary> /// <param name="item">The item to remove from the ArrayEx(T).</param> /// <param name="alloccurrences">True if all occurrences of the item should be removed, False if only the first should be removed.</param> /// <returns>True if an item was removed, false otherwise.</returns> public bool Remove(T item, bool alloccurrences) { int shiftto = 0; bool shiftmode = false; bool removed = false; int count = m_count; EqualityComparer<T> comparer = EqualityComparer<T>.Default; for (int i = 0; i < count; ++i) { if (comparer.Equals(m_data[i], item) && (alloccurrences || !shiftmode)) { // Decrement the count since we have found an instance --m_count; removed = true; // Check to see if we have already found one occurrence of the item we are removing if (!shiftmode) { // We will start shifting to the position of the first occurrence. shiftto = i; // Enable shifting shiftmode = true; } continue; } if (shiftmode) { // Since we are shifting elements we need to shift the element down and then update the shiftto index to the next element. m_data[shiftto++] = m_data[i]; } } for (int i = m_count; i < count; ++i) { m_data[i] = default(T); } if (removed) { ++m_updateCode; } return removed; } /// <summary> /// Removes the item located at the specified index. /// </summary> /// <param name="index">The index of the item to remove</param> public void RemoveAt(int index) { if (index < 0 || index >= m_count) { // Item has already been removed. return; } int count = Count; // Shift all of the elements after the specified index down one. for (int i = index + 1; i < count; ++i) { m_data[i - 1] = m_data[i]; } // Decrement the count to reflect the item being removed. --m_count; ++m_updateCode; m_data[m_count] = default(T); } /// <summary> /// Inserts an item into the ArrayEx(T) at the specified index. /// </summary> /// <param name="index">The zero-based index at which item should be inserted.</param> /// <param name="item">The item to insert.</param> public void Insert(int index, T item) { if (index < 0 || index >= m_count) { throw new ArgumentOutOfRangeException("index"); } if (m_count + 1 >= Capacity) { Capacity = m_count + GROW_BY; } // First we need to shift all elements at the location up by one for (int i = m_count; i > index && i > 0; --i) { m_data[i] = m_data[i - 1]; } m_data[index] = item; ++m_count; ++m_updateCode; } /// <summary> /// Gets or sets an element in the ArrayEx(T). /// </summary> /// <param name="index">The index of the element.</param> /// <returns>The value of the element.</returns> public T this[int index] { get { if (index < 0 || index >= m_count) { throw new ArgumentOutOfRangeException("index"); } return m_data[index]; } set { if (index < 0 || index >= m_count) { throw new ArgumentOutOfRangeException("index"); } m_data[index] = value; ++m_updateCode; } } /// <summary> /// Copies the elements of the ArrayEx(T) to a new array. /// </summary> /// <returns>An array containing copies of the elements of the ArrayEx(T).</returns> public T[] ToArray() { T[] tmp = new T[Count]; for (int i = 0; i < Count; ++i) { tmp[i] = m_data[i]; } return tmp; } }}
测试方法
public static void TestArrayEx() { // Check null indexing ArrayEx<ArrayEx<int>> nullableList = new ArrayEx<ArrayEx<int>>(); nullableList = new ArrayEx<ArrayEx<int>>(); ArrayEx<int> tmpList = new ArrayEx<int>(); nullableList.Add(new ArrayEx<int>()); nullableList.Add(null); nullableList.Add(new ArrayEx<int>()); nullableList.Add(null); nullableList.Add(tmpList); nullableList.Add(null); System.Diagnostics.Debug.Assert(nullableList.Contains(null)); System.Diagnostics.Debug.Assert(nullableList.Contains(tmpList)); System.Diagnostics.Debug.Assert(!nullableList.Contains(new ArrayEx<int>())); ArrayEx<int> list = new ArrayEx<int>(); // Testing the add list.Add(1); list.Add(3); list.Add(4); list.Add(6); list.Add(9); list.Add(5); list.Add(6); list.Add(9); list.Add(9); list.Add(7); List<int> tt = new List<int>(new int[] {1, 3, 4}) ; System.Diagnostics.Debug.Assert(list.Count == 10); // Testing the grow by list.Add(14); list.Add(19); System.Diagnostics.Debug.Assert(list.Count == 12); // Deleting the first 6 from the list list.Remove(6, false); System.Diagnostics.Debug.Assert(list.Contains(6)); System.Diagnostics.Debug.Assert(list.IndexOf(6) == 5); System.Diagnostics.Debug.Assert(list.Count == 11); // Deleting all 9s from the list list.Remove(9, true); System.Diagnostics.Debug.Assert(!list.Contains(9)); System.Diagnostics.Debug.Assert(list.Count == 8); // Inserting a two at the 2nd position list.Insert(1, 2); System.Diagnostics.Debug.Assert(list[1] == 2); System.Diagnostics.Debug.Assert(list[2] == 3); System.Diagnostics.Debug.Assert(list.Count == 9); // Check the DebugView method ArrayDebugView view = new ArrayDebugView(list); object[] values = view.Items; System.Diagnostics.Debug.Assert(values.Length == list.Count); for (int i = 0; i < list.Count; ++i) { System.Diagnostics.Debug.Assert((int)values[i] == list[i]); } // Testing clear list.Clear(); System.Diagnostics.Debug.Assert(list.Count == 0); list.Add(66); list.Add(99); System.Diagnostics.Debug.Assert(list[0] == 66); System.Diagnostics.Debug.Assert(list[1] == 99); // Test removing System.Diagnostics.Debug.Assert(list.Remove(66)); System.Diagnostics.Debug.Assert(!list.Remove(68)); // Prepare for RemoveAt test list.Clear(); list.Add(0); list.Add(1); list.Add(2); list.Add(3); list.Add(4); list.Add(5); list.Add(6); list.Add(7); System.Diagnostics.Debug.Assert(list.Count == 8); // Test RemoveAt the end list.RemoveAt(7); System.Diagnostics.Debug.Assert(list.Count == 7); System.Diagnostics.Debug.Assert(list.Contains(6)); System.Diagnostics.Debug.Assert(!list.Contains(7)); // Test RemoveAt the middle list.RemoveAt(4); System.Diagnostics.Debug.Assert(list.Count == 6); System.Diagnostics.Debug.Assert(list.Contains(3)); System.Diagnostics.Debug.Assert(list.Contains(5)); System.Diagnostics.Debug.Assert(!list.Contains(4)); // Test RemoveAt the front list.RemoveAt(0); System.Diagnostics.Debug.Assert(list.Count == 5); System.Diagnostics.Debug.Assert(list.Contains(1)); System.Diagnostics.Debug.Assert(!list.Contains(0)); }
- 使用Array的一个扩展类,允许Add,Remove,Contains
- 使用SingleLinkedList扩展类,允许Add,Remove,Contains
- 使用DoubleLinkedList扩展类,允许Add,Remove,Contains
- 数据结构之解析ArrayList源码的add,remove,set,contains
- (日常打卡)自定义的一个模仿ArrayList的类, 你需要实现其中的add, get, remove , 等方法
- EventListener的add和remove
- List的contains()和remove()方法探讨
- 在Array原型链上扩展remove,contain等方法所遇到的坑
- Javascript中的Array的Remove
- javascript中扩展Array类的原型
- 高级for循环使用remove/add 问题
- C#ArrayList Add AddRange Remove RemoveAt Reverse Sort Insert InsertRange Contains Count Capacity
- 迭代(遍历)时候不可以使用集合的remove和add方法,但可使用Java迭代器的remove和add方法
- javascript扩展Array类
- js中给Array添加一个contains方法。
- 非常好的javascript:add event/ remove event
- 模拟 List 的 add 和 remove
- ArrayList的add和remove方法
- arm-marvell-linux-gnueabi 交叉编译c/c++程序,并移植到android
- CSS之基础语法
- 如何调试makefile
- ASP.NET 4.0 与 Entity Framework 4-第一篇-采用Model-First 开发方式创建数据库
- 游标之数据转换模板
- 使用Array的一个扩展类,允许Add,Remove,Contains
- C++函数返回引用
- Eclipse快捷键大全
- Jsp基础(二)
- VisionMobile:从MeeGo到Tizen:制造另一个软件泡沫
- DEDECMS后台频道管理员权限三级子栏目权限添加分配问题解决
- 进程管理之schedule()
- WSADATA
- runtest