1. 程式人生 > 其它 >C#集合

C#集合

集合

1. HashMap

.Net中沒有HashMap

2. HashTable

2.1 散列表

散列表:也叫雜湊表,是根據關鍵碼值(Key value)而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中一個位置來訪問記錄,以加速查詢的速度。這個對映的函式叫做雜湊函式,存放記錄的陣列叫做散列表

給定表M,存在函式f(key),對任意給定的關鍵字值key,代入函式後若能得到包含該關鍵字的記錄在表中的地址,則稱表M為雜湊(Hash)表,函式f(key)為雜湊(Hash) 函式。

基本思想:記錄的儲存位置與關鍵字之間存在對應關係。

​ 對應關係----hash函式

​ Loc(i)=H(keyi)

2.2 Hashtable 類_MS

表示根據鍵的雜湊程式碼進行組織的鍵/值對的集合。

備註:

  1. 每個元素都是儲存在物件DictionaryEntry 中的鍵/值對 。 鍵不能為 null ,但值可以為null

  2. Hashtable是執行緒安全的

3. Dictionary<T1,T2>

表示鍵和值的集合。

4. List

表示可通過索引訪問的物件的強型別列表。 提供用於對列表進行搜尋、排序和操作的方法。

下面的示例演示如何在中新增、移除和插入簡單的業務物件 List

using System;
using System.Collections.Generic;
// Simple business object. A PartId is used to identify the type of part
// but the part name can change.
public class Part : IEquatable<Part>
    {
        public string PartName { get; set; }

        public int PartId { get; set; }

        public override string ToString()
        {
            return "ID: " + PartId + "   Name: " + PartName;
        }
        public override bool Equals(object obj)
        {
            if (obj == null) return false;
            Part objAsPart = obj as Part;
            if (objAsPart == null) return false;
            else return Equals(objAsPart);
        }
        public override int GetHashCode()
        {
            return PartId;
        }
        public bool Equals(Part other)
        {
            if (other == null) return false;
            return (this.PartId.Equals(other.PartId));
        }
    // Should also override == and != operators.
    }
public class Example
{
    public static void Main()
    {
        // Create a list of parts.
        List<Part> parts = new List<Part>();

        // Add parts to the list.
        parts.Add(new Part() { PartName = "crank arm", PartId = 1234 });
        parts.Add(new Part() { PartName = "chain ring", PartId = 1334 });
        parts.Add(new Part() { PartName = "regular seat", PartId = 1434 });
        parts.Add(new Part() { PartName = "banana seat", PartId = 1444 });
        parts.Add(new Part() { PartName = "cassette", PartId = 1534 });
        parts.Add(new Part() { PartName = "shift lever", PartId = 1634 });

        // Write out the parts in the list. This will call the overridden ToString method
        // in the Part class.
        Console.WriteLine();
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }

        // Check the list for part #1734. This calls the IEquatable.Equals method
        // of the Part class, which checks the PartId for equality.
        Console.WriteLine("\nContains(\"1734\"): {0}",
        parts.Contains(new Part { PartId = 1734, PartName = "" }));

        // Insert a new item at position 2.
        Console.WriteLine("\nInsert(2, \"1834\")");
        parts.Insert(2, new Part() { PartName = "brake lever", PartId = 1834 });

        //Console.WriteLine();
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }

        Console.WriteLine("\nParts[3]: {0}", parts[3]);

        Console.WriteLine("\nRemove(\"1534\")");

        // This will remove part 1534 even though the PartName is different,
        // because the Equals method only checks PartId for equality.
        parts.Remove(new Part() { PartId = 1534, PartName = "cogs" });

        Console.WriteLine();
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }
        Console.WriteLine("\nRemoveAt(3)");
        // This will remove the part at index 3.
        parts.RemoveAt(3);

        Console.WriteLine();
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }

            /*

             ID: 1234   Name: crank arm
             ID: 1334   Name: chain ring
             ID: 1434   Name: regular seat
             ID: 1444   Name: banana seat
             ID: 1534   Name: cassette
             ID: 1634   Name: shift lever

             Contains("1734"): False

             Insert(2, "1834")
             ID: 1234   Name: crank arm
             ID: 1334   Name: chain ring
             ID: 1834   Name: brake lever
             ID: 1434   Name: regular seat
             ID: 1444   Name: banana seat
             ID: 1534   Name: cassette
             ID: 1634   Name: shift lever

             Parts[3]: ID: 1434   Name: regular seat

             Remove("1534")

             ID: 1234   Name: crank arm
             ID: 1334   Name: chain ring
             ID: 1834   Name: brake lever
             ID: 1434   Name: regular seat
             ID: 1444   Name: banana seat
             ID: 1634   Name: shift lever

             RemoveAt(3)

             ID: 1234   Name: crank arm
             ID: 1334   Name: chain ring
             ID: 1834   Name: brake lever
             ID: 1444   Name: banana seat
             ID: 1634   Name: shift lever


         */
    }
}

DataTable

表示記憶體中資料的一個表。

// Put the next line into the Declarations section.
private System.Data.DataSet dataSet;

private void MakeDataTables()
{
    // Run all of the functions.
    MakeParentTable();
    MakeChildTable();
    MakeDataRelation();
    BindToDataGrid();
}

private void MakeParentTable()
{
    // Create a new DataTable.
    System.Data.DataTable table = new DataTable("ParentTable");
    // Declare variables for DataColumn and DataRow objects.
    DataColumn column;
    DataRow row;

    // Create new DataColumn, set DataType,
    // ColumnName and add to DataTable.
    column = new DataColumn();
    column.DataType = System.Type.GetType("System.Int32");
    column.ColumnName = "id";
    column.ReadOnly = true;
    column.Unique = true;
    // Add the Column to the DataColumnCollection.
    table.Columns.Add(column);

    // Create second column.
    column = new DataColumn();
    column.DataType = System.Type.GetType("System.String");
    column.ColumnName = "ParentItem";
    column.AutoIncrement = false;
    column.Caption = "ParentItem";
    column.ReadOnly = false;
    column.Unique = false;
    // Add the column to the table.
    table.Columns.Add(column);

    // Make the ID column the primary key column.
    DataColumn[] PrimaryKeyColumns = new DataColumn[1];
    PrimaryKeyColumns[0] = table.Columns["id"];
    table.PrimaryKey = PrimaryKeyColumns;

    // Instantiate the DataSet variable.
    dataSet = new DataSet();
    // Add the new DataTable to the DataSet.
    dataSet.Tables.Add(table);

    // Create three new DataRow objects and add
    // them to the DataTable
    for (int i = 0; i<= 2; i++)
    {
        row = table.NewRow();
        row["id"] = i;
        row["ParentItem"] = "ParentItem " + i;
        table.Rows.Add(row);
    }
}

private void MakeChildTable()
{
    // Create a new DataTable.
    DataTable table = new DataTable("childTable");
    DataColumn column;
    DataRow row;

    // Create first column and add to the DataTable.
    column = new DataColumn();
    column.DataType= System.Type.GetType("System.Int32");
    column.ColumnName = "ChildID";
    column.AutoIncrement = true;
    column.Caption = "ID";
    column.ReadOnly = true;
    column.Unique = true;

    // Add the column to the DataColumnCollection.
    table.Columns.Add(column);

    // Create second column.
    column = new DataColumn();
    column.DataType= System.Type.GetType("System.String");
    column.ColumnName = "ChildItem";
    column.AutoIncrement = false;
    column.Caption = "ChildItem";
    column.ReadOnly = false;
    column.Unique = false;
    table.Columns.Add(column);

    // Create third column.
    column = new DataColumn();
    column.DataType= System.Type.GetType("System.Int32");
    column.ColumnName = "ParentID";
    column.AutoIncrement = false;
    column.Caption = "ParentID";
    column.ReadOnly = false;
    column.Unique = false;
    table.Columns.Add(column);

    dataSet.Tables.Add(table);

    // Create three sets of DataRow objects,
    // five rows each, and add to DataTable.
    for(int i = 0; i <= 4; i ++)
    {
        row = table.NewRow();
        row["childID"] = i;
        row["ChildItem"] = "Item " + i;
        row["ParentID"] = 0 ;
        table.Rows.Add(row);
    }
    for(int i = 0; i <= 4; i ++)
    {
        row = table.NewRow();
        row["childID"] = i + 5;
        row["ChildItem"] = "Item " + i;
        row["ParentID"] = 1 ;
        table.Rows.Add(row);
    }
    for(int i = 0; i <= 4; i ++)
    {
        row = table.NewRow();
        row["childID"] = i + 10;
        row["ChildItem"] = "Item " + i;
        row["ParentID"] = 2 ;
        table.Rows.Add(row);
    }
}

private void MakeDataRelation()
{
    // DataRelation requires two DataColumn
    // (parent and child) and a name.
    DataColumn parentColumn =
        dataSet.Tables["ParentTable"].Columns["id"];
    DataColumn childColumn =
        dataSet.Tables["ChildTable"].Columns["ParentID"];
    DataRelation relation = new
        DataRelation("parent2Child", parentColumn, childColumn);
    dataSet.Tables["ChildTable"].ParentRelations.Add(relation);
}

private void BindToDataGrid()
{
    // Instruct the DataGrid to bind to the DataSet, with the
    // ParentTable as the topmost DataTable.
    dataGrid1.SetDataBinding(dataSet,"ParentTable");
}

註解

DataTable是 ADO.NET 庫中的中心物件。 使用的其他物件 DataTable 包括 DataSetDataView

在訪問 DataTable 物件時,請注意,它們具有條件區分大小寫。 例如,如果一個 DataTable 名為 "mydatatable",另一個名為 "mydatatable",則用於搜尋其中一個表的字串被視為區分大小寫。 但是,如果 "mydatatable" 存在並且 "Mydatatable" 不是,則搜尋字串將被視為不區分大小寫。 DataSet可以包含兩個 DataTable 物件,這些物件具有相同的 TableName 屬性值,但 Namespace 屬性值不同。 有關使用物件的詳細資訊 DataTable ,請參閱 建立 DataTable

如果要 DataTable 以程式設計方式建立,則必須先通過將 DataColumn 物件新增到 DataColumnCollection 通過屬性) 訪問 (來定義其架構 Columns 。 有關新增物件的詳細資訊 DataColumn ,請參閱 將列新增到 DataTable

若要將行新增到 DataTable 中,必須首先使用 NewRow 方法返回新的 DataRow 物件。 NewRow方法返回一個具有架構的行 DataTable ,因為它是由表的定義的 DataColumnCollection 。 可儲存的最大行數 DataTable 為16777216。 有關詳細資訊,請參閱 將資料新增到 DataTable

DataTable還包含一個 Constraint 物件集合,這些物件可用於確保資料的完整性。 有關詳細資訊,請參閱 DataTable 約束

DataTable可以使用多個事件來確定何時對錶進行了更改。 其中包括 RowChangedRowChangingRowDeletingRowDeleted。 有關可與一起使用的事件的詳細資訊 DataTable ,請參閱 處理 DataTable 事件

建立的例項後 DataTable ,某些讀/寫屬性將設定為初始值。 有關這些值的列表,請參閱 DataTable.DataTable 建構函式主題。

.net 中沒有HashMap

HashTable和Dictionary總結

  1. Hashtable和Dictionary從資料結構上來說都屬於Hashtable,都是對關鍵字(鍵值)進行雜湊操作,將關鍵字雜湊到Hashtable的某一個槽位中去,不同的是處理碰撞的方法。雜湊函式有可能將不同的關鍵字雜湊到Hashtable中的同一個槽中去,這個時候我們稱發生了碰撞,為了將資料插入進去,我們需要另外的方法來解決這個問題。

Dictionary<T1,T2>和List

List就是一個集合,它可以儲存某種型別的列表

Dictionary<T1,T2> 字典,它包含一個Key和與之對應的Value,其目的是根據key迅速地找到Value,演算法複雜度為O(1).

參考資料

閒話Hashtable與Dictionary

Dictionary和List哪個效率更好

Dictionary<TKey,TValue> 類_MS

List類 MS

Hashtable類 MS