【类库】容器对象(List、DataTable、 DataView、Dictionary)
首先申明一下,写此博文的目的是纪录一下,知识都是现成的,只是整理一下,为了让自己更容易看懂,比在其他地方更容易明白。因为它们太常用了,不忍心每次都去用那么长的时间查看MSDN,希望能在这里用理少的时间来理解并运用其用法。最终目标是减少从接触到能理解并使用的时间。
List<T>类型的查找操作Find与FindIndex
Point pt;
List<Point> lstPs = new List<Point>();
for (int i = ; i < ; i++)
{
pt = new Point(i, i + );
lstPs.Add(pt);
}
Point pp = lstPs.Find( delegate(Point p)//pp是结果Point,是查到的目标
{
return p.X == ;//这个是有目标的情况,如果没有这个X==9的这个点呢?
});
Point ppNo = lstPs.Find(delegate(Point p)
{
return p.X == ;//如果队列中没有目标点,返回的是Point类型的默认值
});
Console.WriteLine("目标点是:"+pp);
Console.WriteLine("没有发现目标点时得到的是默认值:" + ppNo);
/*
返回结果如下:
目标点是:{X=9,Y=109}
没有发现目标点时得到的是默认值:{X=0,Y=0}
*/
List过滤
结论:使用Find方法时要注意return 语句后面是bool类型的表达式,不是想当然的返回一个目标T类型,这里是Point类型。在List中有目标就查到目标,如果没有话就返回 T类型的默认值(default(T)可得到)。
FindIndex:
//名字 值 单位组合 nvu
struct NameValueUnit
{
public string oname;
public string ovalue;
public string ounit;
}
//移除一个组合
public void RemoveByName(string name)
{
int index = -;
index = lstNVU.FindIndex(delegate(NameValueUnit nvu)
{
if (nvu.oname.Equals(name))
{
return true;
}
else
{
return false;
}
});
lstNVU.RemoveAt(index);
}
FindIndex的使用
下面来看看FindAll的源码:
public List<T> FindAll(Predicate<T> match) {
if( match == null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock();
List<T> list = new List<T>();
for(int i = ; i < _size; i++) {
if(match(_items[i])) {
list.Add(_items[i]);
}
}
return list;
}
FindAll
主要依赖Predicate委托,那看一下这个委托:
public delegate bool Predicate<in T>(T obj);
传入一个用于判断满足条件的委托实例,就可以得到目标数据。很巧妙!。
List查询最近值
//List获取最近值原理。
//从List中寻找离number最近的数
list.Aggregate((x,y) => Math.Abs(x-number) < Math.Abs(y-number) ? x : y);
//从源码上看是遍历所有元素,时间复杂度是O(n);
最近值
DataTable的使用
1、添加列
2、添加行
3、查找数据select方法的使用
4、获取列名
DataTable dtAll = new DataTable();
//下面建立列过程:分别添加名为ID的列,名为name的列,名为score的列,类型分别是long,string,float。
DataColumn dc = new DataColumn("ID", typeof(long));
dtAll.Columns.Add(dc);
dc = new DataColumn("name", typeof(string));
dtAll.Columns.Add(dc);
dc = new DataColumn("score", typeof(float));
dtAll.Columns.Add(dc);
//为表添加行
DataRow dr = dtAll.NewRow();
dr[] = ;//其实是一个装箱过程,把int装箱为object
dr[] = "john";
dr[] = 98.5;
dtAll.Rows.Add(dr);
dr = dtAll.NewRow();
dr[] = ;
dr[] = "Lucy";
dr[] = 23.5;
dtAll.Rows.Add(dr);
DataRow[] drs = dtAll.Select("ID=2009000");
Console.WriteLine(drs[][]);//查找到的第一个人的分数score,结果是当然的98.5
添加行和列
几个需要注意的地方。第一、先添加列,而不是先添加行,在添加列后再补充每行;第二、向第n行的第m列添加数据时是一个装箱过程,取出目标数据时需要拆箱操作,一般是Convert.To***方法;第三、查寻时的过滤条件是string,语法是SQL相仿。
一个例子:查找条件不同时的结果。
DataTable dt = new DataTable();
for (int i = ; i < ; i++)//加两列
{
DataColumn dc = new DataColumn();
if (i == )
{
dc.ColumnName = "we";
dc.DataType = typeof(int);
}
dt.Columns.Add(dc);
} DataRow dr = dt.NewRow();
dr[] = ;
dr[] = "ddd";
dt.Rows.Add(dr); dr = dt.NewRow();
dr[] = ;
dr[] = "";
dt.Rows.Add(dr); string condition = "we>70 and we<" + ;
DataRow[] drs = dt.Select(condition);
string tmp = drs[][].ToString();//能输出正常结果,根据条件condition的不同输出不同的结果
Console.WriteLine(tmp);
Select条件查找的使用
condition作为条件,使用SQL语法 .
要获取列名只用一条语句 :
dataTable.Columns[i].ColumnName;//得到第i列的列名
5、复制表结构
DataTable dt2 = dt1.Clone();//这样把表dt1的结构复制到表dt2中,但是不复制数据
6、得到DataTable的第begin行到第end行的数据,并返回一个过滤后的DataTable
/// <summary>
/// 过滤第begin行到到end行之间的数据行
/// </summary>
/// <param name="begin">开始行</param>
/// <param name="end">结束行</param>
/// <param name="oDT">源表</param>
/// <returns></returns>
public static DataTable DtSelectRows(int begin,int end, DataTable oDT)
{ if (oDT.Rows.Count < end) return oDT;
DataTable NewTable = oDT.Clone();
DataRow[] rows = oDT.Select("1=1");
for (int i = begin; i <=end; i++)
{
NewTable.ImportRow((DataRow)rows[i]);
}
return NewTable;
}
过滤第begin行到到end行之间的数据行
交换两行
public static DataTable SwapRow(int index1, int index2, DataTable dt)
{
DataRow dr = dt.NewRow();
dr.ItemArray = dt.Rows[index1].ItemArray;
dt.Rows[index1].ItemArray = dt.Rows[index2].ItemArray;
dt.Rows[index2].ItemArray = dr.ItemArray;
return dt;
}
交换两行
DataView的一些用法
1、使用DataTable得到DataView时一个问题
原始有问题的代码如下:
DataView dvClass = booksClass.dtClass.DefaultView;
DataView dvChild = booksClass.dtClass.DefaultView;
dvClass.RowFilter="father='11'";
dvChild.RowFilter = "father='22'";
这样做后,回头再看发现dvClass 和 dvChild的RowFilter是相同的,都是"father='22'";原来是因为dvClass dvChild引用了同一个实例。所以修改如下:
DataView dvChild = new DataView(booksClass.dtClass);// booksClass.dtClass.DefaultView;
dvClass.RowFilter = "father='11'";
dvChild.RowFilter = "father='222'";
问题得以解决,两个DataView就变得独立了。
List的排序
private void InitSS()
{
List<MyStruct> lstStructs = new List<MyStruct>(); MyStruct ms1, ms2, ms3, ms4;
ms1.age = ;
ms1.name = "aa";
lstStructs.Add(ms1); ms2.age = ;
ms2.name = "bb";
lstStructs.Add(ms2); ms3.age = ;
ms3.name = "dd";
lstStructs.Add(ms3); ms4.age = ;
ms4.name = "ss";
lstStructs.Add(ms4); textBox1.Text = string.Empty; textBox1.Text += "排序前:\r\n";
foreach (var item in lstStructs)
{
//Console.WriteLine(item.Id + "," + item.Name);
textBox1.Text += item.age + ":" + item.name + "\r\n";
} lstStructs.Sort(delegate(MyStruct info1, MyStruct info2)
{
return info1.age.CompareTo(info2.age);//排序的关键
});
//Console.WriteLine("*****ListSort**********");
textBox1.Text += "排序后:\r\n";
foreach (var item in lstStructs)
{
//Console.WriteLine(item.Id + "," + item.Name);
textBox1.Text += item.age + ":" + item.name + "\r\n";
}
} private void btnSsort_Click(object sender, EventArgs e)
{
InitSS();
}
} struct MyStruct
{
public int age;
public string name;
}
排序示例
5、复制表结构
Dictionary
1、根据value得到key
var firstKey = dic.FirstOrDefault(q => q.Value == "").Key; //get first key 其中q为一个键值对
两个List<>互相过滤数据
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace AboutList
{
class Program
{
static void Main(string[] args)
{
Student s1 = new Student { Age=,Name="deng"};
Student s2 = new Student { Age = , Name = "li" };
Student s3 = new Student { Age = , Name = "张" };
Student s4 = new Student { Age = , Name = "王" };
Student s5 = new Student { Age = , Name = "李" };
List<Student> list1 = new List<Student> { s1, s2, s3, s4, s5 };
List<Student> list2 = new List<Student> { s1,s2};
//下面查找不在list2中,只在list1中的Student实例
List<Student> listRes = list1.FindAll(delegate(Student s)
{
int index = list2.FindIndex(delegate(Student ss)
{
return ss == s;
});
if (index >= )
{
return false;
}
else
{
return true;
}
});
//输出看结果
foreach (var s in listRes)
{
Console.WriteLine("Name=" + s.Name + "; Age=" + s.Age);
} Console.Read();
}
} class Student
{
public int Age
{
get;
set;
} public string Name
{
get;
set;
}
}
}
List删除 重复数据
// 不能用foreach,因为迭代器是只读的
for (int i = ; i < strs.Count; i++)
{
// 如果第一次出现的位置不等于最后一次出现的位置,则说明该元素不止出现一次
if (strs.IndexOf(strs[i]) != strs.LastIndexOf(strs[i]))
{
strs.RemoveAt(strs.LastIndexOf(strs[i]));
}
}
删除重复
ddd
ddd
ddd
ddd
ddd
ddd
【类库】容器对象(List、DataTable、 DataView、Dictionary)的更多相关文章
- 【Spring】手动获取spring容器对象时,报no qualifying bean of type is defined
手动获取容器对象时,报no qualifying bean of type is defined, 经过调查,发现手动获取的时候,该类所在的包必须经过spring容器初始化. 1.SpringConf ...
- C++ 容器对象vector和list 的使用
在<<c++ primer>>第四版Exercise Section 9.3.4 的Exercise 9.20 是这样的一道题目:编写程序判断一个vector<int&g ...
- 获取spring容器对象方法和原因
为什么要获取Spring容器对象:拿到spring容器对象后,你就可以用spring管理的bean了,拿到bean,自然可以使用bean的方法,场景:比如jsp页面.通过注解是无法注入bean的,在开 ...
- 配置Spring的用于初始化容器对象的监听器
<!-- 配置Spring的用于初始化容器对象的监听器 --> <listener> <listener-class>org.springframework.web ...
- javascript客户端遍历控件与获取父容器对象
javascript客户端遍历控件与获取父容器对象示例代码 1,遍历也面中所有的控件function findControlAll() { var inputs=document. ...
- 将Spring容器跟随系统启动并获取容器对象
将Spring容器随系统启动的方法: 在web.xml中配置监听器,监听的对象为ContextLoaderListener <listener> <listener-class> ...
- 条目七《如果容器中包含了通过new操作创建的指针,切记在容器对象析构前将指针delete掉》
如果容器中包含了通过new操作创建的指针,切记在容器对象析构前将指针delete掉 在STL中容器是智能的,可以在容器销毁时自动调用容器里对象的析构函数来销毁容器存储的对象. STL的容器虽然比较智能 ...
- DataSet,DataTable,DataView、DataRelation
一.创建Dataset和DataTable DataSet ds = new DataSet();//DataSetName默认为"NewDataSet" DataTable ta ...
- ADO.NET对象之 DataTable
ADO.NET可以在与数据库断开连接的方式下通过DataSet或DataTable对象进行数据处理,当需要更新数据时才重新与数据源进行连接,并更新数据源. DataTable对象表示保存在本机内存中的 ...
随机推荐
- mysql while,loop,repeat循环,符合条件跳出循环
1.while循环 DELIMITER $$ DROP PROCEDURE IF EXISTS `sp_test_while`$$ CREATE PROCEDURE `sp_test_while`( ...
- [Java入门笔记] 面向对象编程基础(三):成员变量和局部变量
在类中,变量根据定义的位置不同,可以分为成员变量和局部变量.
- Windows Server 2012 虚拟化实战:域
在Windows Server系统中,一些服务必需要构建在域的环境中,这不仅是为了统一验证和资源共享,同时也是为了网络安全.为构建虚拟化测试,我们需要先搭建域环境.之前先来大概了解一下域. 在使用工作 ...
- Android开机启动程序
android程序实现开机启动的原理,简单点说就是做一个广播接收器,接收到开机广播时就启动activity或service或执行其它操作.Android系统在启动的时候会发出一个开机广播,内容为ACT ...
- spf13-vim安装与使用
一.简介 spf13-vim是Vim插件与配置的一个发行版本,包含了一整套精心挑选的Vim插件,采用Vundle进行插件管理,并且可以通过下列文件进行个性化配置 ~/.vimrc.local #个性化 ...
- WIN7下django1.8下载安装
前言:公司电脑上django是在pycharm上下载自动安装的,家里电脑没安pycharm,所以自己手动安装. django下载地址:https://www.djangoproject.com/dow ...
- 关于css的一些事情(1)
什么情况下hidden不起作用? position设置成fixed,overflow的hidden不起作用. visibility和display 1.visibility: 规定了元素是否可见,即使 ...
- 第38课 Qt中的事件处理(上)
1. GUI程序原理回顾 (1)图形界面应用程序的消息处理模型 (2)思考:操作系统发送的消息如何转变为Qt信号 2. Qt中的事件处理 (1)Qt平台将系统产生的消息转换为Qt事件 ①Qt事件是一个 ...
- Java面向对象 第一章 面向对象开发方法概述
一.软件开发经历的生命周期: ①软件分析 ②软件设计 ③软件编码 ④ 软件测试 ⑤ 软件部署 ⑥软件维护 二.为了提高软件开发效率,降低软件开发成本,一个优良的软件系统应该具备以下特点: ① 可重用性 ...
- EasyUI实现工地领款单项目
环境搭建 引入jar.配置Spring MVC.web.xml.日志等 建表 自动生成MyBatis相关文件 mybatis-generator-core-1.3.2.jar <?xml ver ...