使用Array的一个扩展类,允许Add,Remove,Contains

news/2024/7/4 1:20:32 标签: 扩展, list, testing, null, class, exception
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

类代码

class="language-csharp">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;
        }
    }
}

测试方法

class="language-csharp">        public static void TestArrayEx()
        {
            // Check class="tags" href="/tags/NULL.html" title=null>null indexing
            ArrayEx<ArrayEx<int>> class="tags" href="/tags/NULL.html" title=null>nullableList = new ArrayEx<ArrayEx<int>>();
            class="tags" href="/tags/NULL.html" title=null>nullableList = new ArrayEx<ArrayEx<int>>();
            ArrayEx<int> tmpList = new ArrayEx<int>();
            class="tags" href="/tags/NULL.html" title=null>nullableList.Add(new ArrayEx<int>());
            class="tags" href="/tags/NULL.html" title=null>nullableList.Add(class="tags" href="/tags/NULL.html" title=null>null);
            class="tags" href="/tags/NULL.html" title=null>nullableList.Add(new ArrayEx<int>());
            class="tags" href="/tags/NULL.html" title=null>nullableList.Add(class="tags" href="/tags/NULL.html" title=null>null);
            class="tags" href="/tags/NULL.html" title=null>nullableList.Add(tmpList);
            class="tags" href="/tags/NULL.html" title=null>nullableList.Add(class="tags" href="/tags/NULL.html" title=null>null);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/NULL.html" title=null>nullableList.Contains(class="tags" href="/tags/NULL.html" title=null>null));
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/NULL.html" title=null>nullableList.Contains(tmpList));
            System.Diagnostics.Debug.Assert(!class="tags" href="/tags/NULL.html" title=null>nullableList.Contains(new ArrayEx<int>()));

            ArrayEx<int> class="tags" href="/tags/LIST.html" title=list>list = new ArrayEx<int>();

            // Testing the add
            class="tags" href="/tags/LIST.html" title=list>list.Add(1);
            class="tags" href="/tags/LIST.html" title=list>list.Add(3);
            class="tags" href="/tags/LIST.html" title=list>list.Add(4);
            class="tags" href="/tags/LIST.html" title=list>list.Add(6);
            class="tags" href="/tags/LIST.html" title=list>list.Add(9);
            class="tags" href="/tags/LIST.html" title=list>list.Add(5);
            class="tags" href="/tags/LIST.html" title=list>list.Add(6);
            class="tags" href="/tags/LIST.html" title=list>list.Add(9);
            class="tags" href="/tags/LIST.html" title=list>list.Add(9);
            class="tags" href="/tags/LIST.html" title=list>list.Add(7);

            List<int> tt = new List<int>(new int[] {1, 3, 4}) ;
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Count == 10);

            // Testing the grow by
            class="tags" href="/tags/LIST.html" title=list>list.Add(14);
            class="tags" href="/tags/LIST.html" title=list>list.Add(19);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Count == 12);

            // Deleting the first 6 from the class="tags" href="/tags/LIST.html" title=list>list
            class="tags" href="/tags/LIST.html" title=list>list.Remove(6, false);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Contains(6));
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.IndexOf(6) == 5);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Count == 11);

            // Deleting all 9s from the class="tags" href="/tags/LIST.html" title=list>list
            class="tags" href="/tags/LIST.html" title=list>list.Remove(9, true);
            System.Diagnostics.Debug.Assert(!class="tags" href="/tags/LIST.html" title=list>list.Contains(9));
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Count == 8);

            // Inserting a two at the 2nd position
            class="tags" href="/tags/LIST.html" title=list>list.Insert(1, 2);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list[1] == 2);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list[2] == 3);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Count == 9);

            // Check the DebugView method
            ArrayDebugView view = new ArrayDebugView(class="tags" href="/tags/LIST.html" title=list>list);
            object[] values = view.Items;
            System.Diagnostics.Debug.Assert(values.Length == class="tags" href="/tags/LIST.html" title=list>list.Count);
            for (int i = 0; i < class="tags" href="/tags/LIST.html" title=list>list.Count; ++i)
            {
                System.Diagnostics.Debug.Assert((int)values[i] == class="tags" href="/tags/LIST.html" title=list>list[i]);
            }

            // Testing clear
            class="tags" href="/tags/LIST.html" title=list>list.Clear();
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Count == 0);
            class="tags" href="/tags/LIST.html" title=list>list.Add(66);
            class="tags" href="/tags/LIST.html" title=list>list.Add(99);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list[0] == 66);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list[1] == 99);

            // Test removing
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Remove(66));
            System.Diagnostics.Debug.Assert(!class="tags" href="/tags/LIST.html" title=list>list.Remove(68));

            // Prepare for RemoveAt test
            class="tags" href="/tags/LIST.html" title=list>list.Clear();
            class="tags" href="/tags/LIST.html" title=list>list.Add(0);
            class="tags" href="/tags/LIST.html" title=list>list.Add(1);
            class="tags" href="/tags/LIST.html" title=list>list.Add(2);
            class="tags" href="/tags/LIST.html" title=list>list.Add(3);
            class="tags" href="/tags/LIST.html" title=list>list.Add(4);
            class="tags" href="/tags/LIST.html" title=list>list.Add(5);
            class="tags" href="/tags/LIST.html" title=list>list.Add(6);
            class="tags" href="/tags/LIST.html" title=list>list.Add(7);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Count == 8);

            // Test RemoveAt the end
            class="tags" href="/tags/LIST.html" title=list>list.RemoveAt(7);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Count == 7);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Contains(6));
            System.Diagnostics.Debug.Assert(!class="tags" href="/tags/LIST.html" title=list>list.Contains(7));

            // Test RemoveAt the middle
            class="tags" href="/tags/LIST.html" title=list>list.RemoveAt(4);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Count == 6);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Contains(3));
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Contains(5));
            System.Diagnostics.Debug.Assert(!class="tags" href="/tags/LIST.html" title=list>list.Contains(4));

            // Test RemoveAt the front
            class="tags" href="/tags/LIST.html" title=list>list.RemoveAt(0);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Count == 5);
            System.Diagnostics.Debug.Assert(class="tags" href="/tags/LIST.html" title=list>list.Contains(1));
            System.Diagnostics.Debug.Assert(!class="tags" href="/tags/LIST.html" title=list>list.Contains(0));
        }



http://www.niftyadmin.cn/n/1411650.html

相关文章

Java多线程学习1,使用线程的三种方式

java使用线程有三种方式 1&#xff0c;创建一个类继承Thread类 示例代码 public class Thread1 {public static void main(String[] args) {ThreadA threadA new ThreadA();threadA.start();System.out.println("这是主线程");} }class ThreadA extends Thread {O…

深度理解redux(一)

1、redux作为react技术栈系列中解决数据管理的一种架构&#xff0c;我们非常有必要学会它&#xff0c;理解它。 2、为什么要用redux&#xff1f;很多人很疑惑。有这么一句话&#xff0c;我觉得很经典&#xff0c;就是当你不知道要不要用redux的时候&#xff0c;那就不需要使用…

《树莓派渗透测试实战》——1.3 准备microSD卡

本节书摘来异步社区《树莓派渗透测试实战》一书中的第1章&#xff0c;第1.3节&#xff0c;作者 【美】Joseph Muniz&#xff08;约瑟夫 穆尼斯&#xff09; , Aamir Lakhani&#xff08;阿米尔 拉克哈尼&#xff09;&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号…

使用SingleLinkedList扩展类,允许Add,Remove,Contains

创建两个类 SingleLinkedList<T>using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics;namespace DevGuideToCollections {/// <summary>/// Represents a strongly typed single linked list./// &l…

java多线程学习2,线程的属性

示例代码 public class ThreadProperty {public static void main(String[] args) {TestThread testThread new TestThread();for (int i 0; i < 5; i) {Thread t new Thread(testThread, "name" (i 1));t.setPriority(10 - i);if (i 1)t.setDaemon(true);t…

深度理解redux(二)

1、前一篇说了redux的一些基本概念和用法&#xff0c;这一篇我们研究在react中如何使用redux&#xff0c;在react中使用redux的一些不同点。 2、redux中&#xff0c;我们通过store.subscribe()进行数据监听&#xff0c;来更新页面。在react中&#xff0c;我们针对了redux进行了…

《AutoCAD全套园林图纸绘制自学手册》一2.2 配置绘图系统

本节书摘来自异步社区《AutoCAD全套园林图纸绘制自学手册》一书中的第2章&#xff0c;第2.2节&#xff0c;作者 朱春阳 , 李晓艳 , 胡仁喜&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看 2.2 配置绘图系统 AutoCAD全套园林图纸绘制自学手册由于每台计算机所…

使用DoubleLinkedList扩展类,允许Add,Remove,Contains

方法与SingleLinkedList(单向链表)类似 创建两个泛型类DoubleLinkedList<T>using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics;namespace DevGuideToCollections {/// <summary>/// Represents a …