# Hashtable 哈希表

用于处理和表现类似 key value 的键值对

  • key:通常可用来快速查找,区分大小写
  • value:用于存储对应于 key 的值

Hashtable 中 keyvalue 键值对均为 object 类型,所以 Hashtable 可以支持任何类型的 keyvalue 键值对

# 使用场景

  • 某些数据会被高频率查询
  • 数据量大
  • 查询字段包含字符串类型
  • 数据类型不唯一

# 引入 namespace

using System.Collections;
using System.Collections.Generic;

# 属性

属性描述
Count获取 Hashtable 中包含的键值对个数
IsFixedSize获取一个值,表示 Hashtable 是否具有固定大小
IsReadOnly获取一个值,表示 Hashtable 是否只读
Item获取或设置与指定的键相关的值
Keys获取一个 ICollection,包含 Hashtable 中的键
Values获取一个 ICollection,包含 Hashtable 中的值

# 方法

方法描述
public virtual void Add(object key, object value);添加键值对
public virtual void Remove(object key);移除指定的键值对
public virtual void Clear();移除所有元素
public virtual bool ContainsKey(object key);判断是否包含指定的键 key,返回 true/false
public virtual bool ContainsValue(object value);判断是否包含指定键的 key,返回 true/false
示例
...
using System.Collections; // 必须引入命名空间
using System.Collections.Generic;
namespace HashTable
{
  class Program
  {
    static void Main(string[] args)
    {
      Hashtable ht = new Hashtable();
      ht.Add("北京", "帝都"); // 添加 keyvalue 键值对
      ht.Add("上海", "魔都");
      ht.Add("广州", "省会");
      ht.Add("深圳", "特区");
      Console.WriteLine(ht.Count); // 4,输出键值对个数
      ht.Remove("深圳"); // 移除键值对
      Console.WriteLine(ht.Count); // 3
      Console.WriteLine(ht.Contains("北京")); // True
      Console.WriteLine(ht.ContainsValue("省会")); // True
      Console.WriteLine(ht["上海"]); // 魔都
      ht.Clear(); // 移除所有
    }
  }
}

# 遍历

// 遍历键对
foreach (DictionaryEntry item in ht) {
  Console.WriteLine(item.Key);
  Console.WriteLine(item.Value);
}
// 遍历键
foreach (string key in ht.Keys) {
  Console.WriteLine(key);
}
// 遍历值
foreach (string value in ht.Values) {
  Console.WriteLine(value);
}

# 排序

ArrayList akeys = new ArrayList(ht.Keys);
akeys.Sort(); // 按字母顺序进行排序
foreach (string key in akeys) {
  Console.WriteLine(key + ": " + ht[key]);  // 排序后输出
}
// 输出:
北京: 帝都
广州: 省会
上海: 魔都

# DataTable

DataTable 是一个临时保存数据的网格虚拟表,表示内存中数据的一个表,是一个二维表,也是一个后台数据源和前台显示之间的适配器

# 引入 namespace

using System.Data;

# 属性

属性描述
TableName获取或设置 DataTable 的名称
Columns获取属于该表的列的集合
Rows获取属于该表的行的集合
DataSet获取此表所属的 DataSet
ChildRelations获取此 DataTable 的子关系的集合
Constraints获取由该表维护的约束的集合
DefaultView获取可能包括筛选视图或游标位置的表的自定义视图
CaseSensitive指示表中的字符串比较是否区分大小写
HasErrors获取一个值,该值指示该表所属的 DataSet 的任何表的任何行中是否有错误
MinimumCapacity获取或设置该表最初的起始大小。该表中行的最初起始大小,默认值为 50

# 方法

方法描述
BeginInit()开始初始化在窗体上使用或由另一个组件使用的
DataTable初始化发生在运行时
Clear()清除所有数据的 DataTable
Clone()克隆 DataTable 的结构,包括所有 DataTable 架构和约束
EndInit()结束在窗体上使用或由另一个组件使用的 DataTable 的初 始化。初始化发生在运行时
ImportRow(DataRow row)将 DataRow 复制到 DataTable 中,保留任何属性设置以及初始值和当前值
Merge(DataTable table)将指定的 DataTable 与当前的 DataTable 合并
NewRow()创建与该表具有相同架构的新 DataRow

# 常用使用方法

字段名column0column1
张三DateTime.Now 当前时间
李四DateTime.Now 当前时间

# 创建

// 1、创建一个空表
DataTable dt = new DataTable();
// 2、创建一个名为 "Table_New" 的空表
DataTable dt = new DataTable("Table_New");
// 3、指定的表名和命名空间初始化 DataTable 类的新实例
// DataTable(string tableName, string tableNamespace)
DataTable dt = new DataTable("Table_New","Test");

# 添加列

// 1、创建空列
DataColumn dc = new DataColumn();
dt.Columns.Add(dc);
// 2、创建带列名和类型名的列 (两种方式任选其一)
dt.Columns.Add("column0", System.Type.GetType("System.String"));
dt.Columns.Add("column0", typeof(String));
// 3、通过列架构添加列
DataColumn dc = new DataColumn("column1",System.Type.GetType("System.DateTime"));
DataColumn dc = new DataColumn("column1", typeof(DateTime));
dt.Columns.Add(dc);

# 添加行

// 1、创建空行
DataRow dr = dt.NewRow();
dt.Rows.Add(dr);
// 2、创建空行
dt.Rows.Add();
// 3、通过行框架创建并赋值
dt.Rows.Add("张三", DateTime.Now);// Add 里面参数的数据顺序要和 dt 中的列的顺序对应
// 4、通过复制 dt2 表的某一行来创建
dt.Rows.Add(dt2.Rows[i].ItemArray);

# 赋值取值

赋值

// 1、新建行的赋值
DataRow dr = dt.NewRow();
dr[0] = "张三";// 通过索引赋值
dr["column1"] = DateTime.Now; // 通过名称赋值
// 2、对表已有行进行赋值
dt.Rows[0][0] = "张三"; // 通过索引赋值
dt.Rows[0]["column1"] = DateTime.Now;// 通过名称赋值

取值

string name = dt.Rows[0][0].ToString();
string time = dt.Rows[0]["column1"].ToString();
// 遍历
for (int i = 0; i < dt.Rows.Count; i++) {
  //string strName = dt.Rows [i]["字段名"].ToString ();
  Console.WriteLine(dt.Rows[i]["column0"].ToString());
  Console.WriteLine(dt.Rows[i]["column1"].ToString());
}
foreach (DataRow dr in dt.Rows) {
  //object value = dr ["字段名"];
  Console.WriteLine(dr["column0"]);
  Console.WriteLine(dr["column1"]);
}

# 筛选行

// 选择 column1 列值为空的行的集合
DataRow[] drs = dt.Select("column1 is null");
// 选择 column0 列值为 "李四" 的行的集合
DataRow[] drs = dt.Select("column0 = '李四'");
// 筛选 column0 列值中有 "张" 的行的集合 (模糊查询)
DataRow[] drs = dt.Select("column0 like '张%'"); // 如果的多条件筛选,可以加 and 或 or
// 筛选 column0 列值中有 "张" 的行的集合并按 column1 降序排序
DataRow[] drs = dt.Select("column0 like '张%'", "column1 DESC");
// DataTable.Select () 方法里面支持简单的过滤和排序,不支持复杂的条件过滤和排序。里面的字符串必须是列名和数据,以及>,<,=,<> 等关系运算符
DataRow[] drs = dt.Select("column0 = '李四' and column0 = '1'");

# 删除行

// 1、DataTable.Rows.Remove (DataRow) 方法
dt.Rows.Remove(dt.Rows[0]);
// 2、DataTable.Rows.RemoveAt (index) 方法
dt.Rows.RemoveAt(0);
// 3、DataRow.Delete () 方法
dt.Rows[0].Delete();
dt.AcceptChanges();
//----- ❗ 区别和注意点 -----
// Remove () 和 RemoveAt () 方法是直接删除
// Delete () 方法只是将该行标记为 deleted,但是还存在,还可 DataTable.RejectChanges () 回滚,使该行取消删除
// 用 Rows.Count 来获取行数时,还是删除之前的行数,需要使用 DataTable.AcceptChanges () 方法来提交修改
// 如果要删除 DataTable 中的多行,应该采用倒序循环 DataTable.Rows,而且不能用 foreach 进行循环删除,因为正序删除时索引会发生变化,程式发生异常,很难预料后果
for (int i = dt.Rows.Count - 1; i >= 0; i--)
{
  dt.Rows.RemoveAt(i);
}

# 复制表

复制表 - 同时复制了表结构和数据

// 方法一
DataTable dtNew = new DataTable();
dtNew = dt.Copy();
// 方法二
DataTable dtNew = dt.Copy();
dtNew.Clear(); // 清空数据
for (int i = 0; i < dt.Rows.Count; i++)
{
  if (条件语句)
  {
     dtNew.Rows.Add(dt.Rows[i].ItemArray); // 复制 dt 表来添加数据行
  }
}

克隆表 - 只复制表结构,不包括数据

DataTable dtNew = new DataTable();
dtNew = dt.Clone();
// 如果只需要某个表中的某一行
DataTable dtNew = new DataTable();
dtNew = dt.Copy();
dtNew.Rows.Clear(); // 清空表数据
dtNew.ImportRow(dt.Rows[0]); // 加入 dt 的第一行

# 表排序

// 创建表
DataTable dt = new DataTable();
// 添加列
dt.Columns.Add("ID", typeof(Int32));
dt.Columns.Add("Name", typeof(String));
dt.Columns.Add("Age", typeof(Int32));
// 添加行
dt.Rows.Add(new object[] { 1, "张三" ,20});
dt.Rows.Add(new object[] { 2, "李四" ,25});
dt.Rows.Add(new object[] { 3, "王五" ,30});
// 获取表视图
DataView dv = dt.DefaultView;
dv.Sort = "ID DESC"; // 按照 ID 倒序排序
dv.ToTable(); // 转为表

# DataSet

DataSet ds = new DataSet();
ds.Tables.Add(dt);
ds.Tables.Add(dtSort);
ds.Tables.Add(dtNew2);
foreach (DataTable table in ds.Tables) {
  Console.WriteLine();
    foreach (DataRow rows in table.Rows) { // 遍历每行
      for (int i = 0; i < table.Columns.Count; i++) {
        Console.Write(rows[i] + "\t");
      }
    Console.WriteLine();
  }
}

# DataView

# 三者关系

img

  • DataSet:临时数据库
  • DataTable:临时数据表

# List 集合

List<T> 是一种非常常用的泛型集合类,用于存储一组相同类型的元素

List<T> 具有动态调整大小的能力,可以方便地添加、删除、查找和修改元素,

# 引入 namespace

using System.Collections.Generic;

# 属性

属性用法
Items获取或设置指定索引处的元素
Count返回 List <T> 中存在的元素总数

# 方法

方法用法
AddList <T> 的末尾添加元素
AddRange将指定集合的元素添加到 List <T> 的末尾
BinarySearch搜索元素并返回该元素的索引
ClearList <T> 中删除所有元素
Contains检查指定元素在 List <T> 中是否存在
Find根据指定的谓词函数查找第一个元素
Foreach遍历 List <T>
InsertList <T> 中的指定索引处插入元素
InsertRange在指定的索引处插入另一个集合的元素
Remove删除指定元素的第一次出现
RemoveAt删除指定索引处的元素
RemoveRange删除所有与提供的谓词功能匹配的元素
Sort对所有元素进行排序
TrimExcess将容量设置为实际的元素数
TrueForAll确定 List <T> 中的每个元素是否与指定谓词定义的条件匹配

# 添加元素

// 创建一个整数列表
List<int> numbersList = new List<int>();
// 方式一
numbersList.Add(1);
numbersList.Add(2);
numbersList.Add(3);
// 方式二
List<string> fruitsList = new List<string> { "apple", "orange", "banana" };

# 删除元素

// Remove ():只会删除第一个匹配的元素
fruitsList.Remove("orange");
// RemoveAt ():根据索引从列表中删除元素
fruitsList.RemoveAt(1);
// Clear ():清空整个列表,即删除所有元素
fruitsList.Clear();

# 查找元素

// Contains ():判断列表中是否包含指定元素,返回一个布尔值
bool isContains = fruitsList.Contains("orange"); // True
// IndexOf ():只返回第一个匹配的元素索引
int index = fruitsList.IndexOf("orange"); // 1

# 遍历

// for
for (var i = 0; i < fruitsList.Count; i++) {
  Console.WriteLine(fruitsList[i]);
}
// foreach
foreach (var item in fruitsList) {
  Console.WriteLine(item);
}

# 其它常用方法

List<int> numbersList = new List<int> { 4, 1, 6, 3, 9 };
// Count:获取列表中元素的个数
int count = numbersList.Count; // 5
// Sort ():对列表中的元素进行排序
numbersList.Sort(); // { 1, 3, 4, 6, 9 }
// Reverse ():反转列表中元素的顺序
numbersList.Reverse(); // { 9, 3, 6, 1, 4 }
List<int> numbersList = new List<int> { 1, 2, 3, 4, 5 };
// Find ():查找符合指定条件的第一个元素,如果没有找到,则返回默认值 0
int evenNumber = numbersList.Find(x => x % 2 == 0); // 2,查找第一个偶数元素
// FindAll ():查找符合指定条件的所有元素,返回一个新的 List<T> 列表
List<int> oddNumbers = numbersList.FindAll(x => x % 2 != 0); // {1, 3, 5},查找所有奇数元素
// RemoveAll ():根据指定条件删除所有符合条件的元素
numbersList.RemoveAll(x => x % 2 == 0); // {1, 3, 5},删除所有偶数元素
// ForEach ():对列表中的每个元素执行指定的操作
numbersList.ForEach(x => Console.WriteLine(x * 2)); // { 2, 4, 6, 8, 10 }
// Exists ():判断列表中是否存在符合指定条件的元素,返回一个布尔值
bool isExists = numbersList.Exists(x => x > 3); // True,判断是否存在大于 3 的元素

# List<T> 与数组的比较

🚩 数组:

  • 优点
    • 性能更好:数组在内存中是连续分配的,因此访问元素的性能更好,尤其是对于大量元素的访问
    • 固定长度: 数组的长度一旦确定,就无法更改,这有助于保证数据的稳定性和安全性
    • 多维数组:数组支持多维数组,可以用于表示表格、矩阵等结构
  • 适用场景:当数据集合长度固定且需要频繁访问元素时,可以考虑使用数组

🚩 List<T>

  • 优点
    • 动态调整大小: List<T> 可以根据需要动态调整大小,无需提前指定长度,更加灵活
    • 方便的添加和删除: List<T> 提供了丰富的方法用于添加、删除和修改元素,操作更方便
    • 适应不确定数据量:当数据集合长度不确定,可能需要频繁添加或删除元素时,可以使用 List<T>
  • 适用场景:当数据集合长度不确定,或需要频繁进行添加、删除等操作时,可以考虑使用 List<T>

# Array 数组

# 定义

数组是一个存储相同类型元素的固定大小的顺序集合

# 声明

datatype[] arrayName;
- datatype:存储在数组中的元素的类型
- [ ]:数组的大小
- arrayName:数组的名称
更新于

请我喝奶茶⌯oᴗo⌯

呆鸭 微信支付

微信支付

呆鸭 支付宝

支付宝