常用的对list 数据的一些处理等;
1. List 去除重复.使用重载的Distinct,自定义实现Compare
2.list where查找
3.list判断是否存在符合指定条件的某元素;
4.IEqualityComparer接口的实现,自定义比较判断规则.
5.Stopwatch的使用(侦测代码的执行开销时间);
值类型直接略过,主要是自定义类的部分.
详见代码.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ListDistinct
{
class Program
{
static void Main(string[] args)
{
List<epcData> list = new List<epcData>();
list.Add(new epcData("192.168.1.100","E99999"));
list.Add(new epcData("192.168.1.100", "E99999"));
list.Add(new epcData("192.168.1.100", "E55555"));
list.Add(new epcData("192.168.1.111", "E88888"));
list.Add(new epcData("192.168.1.111", "E66666"));
list.Add(new epcData("192.168.1.111", "E66666"));
list.Add(new epcData("192.168.1.222", "E22222"));
list.Add(new epcData("192.168.1.222", "test"));
list.Add(new epcData("192.168.1.100", "E99999"));
list.Add(new epcData("192.168.1.100", "E99999"));
list.Add(new epcData("192.168.1.100", "E55555"));
list.Add(new epcData("192.168.1.111", "E88888"));
list.Add(new epcData("192.168.1.111", "E66666"));
list.Add(new epcData("192.168.1.111", "E66666"));
list.Add(new epcData("192.168.1.222", "E22222"));
Stopwatch swatch = new Stopwatch();
swatch.Start();
//list是非常灵活的结构,可以使用Where来移除特定条件的元素,比Remove更灵活
list = list.Where(a => a.epc != "test").ToList();
swatch.Stop();
Console.WriteLine("用时:" + swatch.Elapsed.ToString());
Console.WriteLine("old list " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff"));
swatch.Restart();
list.ForEach(item => Console.WriteLine(item.ip + " " + item.epc));
swatch.Stop();
Console.WriteLine("用时:" + swatch.Elapsed.ToString());
swatch.Restart();
Console.WriteLine("new list " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff"));
list.Distinct(new Compare()).ToList().ForEach(item =>
Console.WriteLine(item.ip + " " + item.epc)
);
swatch.Stop();
Console.WriteLine("用时:" + swatch.Elapsed.ToString());
//去重,与执行用时计算;
Console.WriteLine("new list end " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff"));
swatch.Restart();
list = list.Distinct(new LambdaComparer<epcData>((a, b) => a.ip == b.ip && a.epc == b.epc, obj => obj.ToString().GetHashCode())).ToList();
list.ForEach(item => Console.WriteLine(item.ip + " " + item.epc));
Console.WriteLine("new list2 end " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff"));
swatch.Stop();
Console.WriteLine("用时:" + swatch.Elapsed.ToString());
//var newList = list.Where(item => item.ip.Contains("192.168.1.100")).ToList();
var newList = list.Where(item => item.ip == "192.168.1.111").ToList();
newList.ForEach(item => Console.WriteLine(item.ip + " " + item.epc));
//查找是否存在;error
if (list.Contains(new epcData("192.168.1.222", "E22222")))
{
Console.WriteLine("Find!");
}
else
{
Console.WriteLine("not Find!");
}
// Contains在自定义类型的情况下,需要使用重载方法,自定义Compare才能正确比较
if (list.Contains(new epcData("192.168.1.222", "E22222"),new Compare()))
{
Console.WriteLine("new Compare Find!");
}
else
{
Console.WriteLine("new Compare not Find!");
}
swatch.Restart();
//查找是否存在2:find
var ff = list.Find(x => x.epc == "E22222");
if (ff!=null)
{
Console.WriteLine("list.Find:OK " + ff.ip+" "+ff.epc);
}
else
{
Console.WriteLine("list.Find:failed");
}
swatch.Stop();
Console.WriteLine("用时:" + swatch.Elapsed.ToString());
swatch.Restart();
//查找是否存在3;Exists (比较好用的一种方法)
if (list.Exists(item=>item.epc== "E22222"))
{
Console.WriteLine("Exists Find!");
}
else
{
Console.WriteLine("Exists not Find!");
}
swatch.Stop();
Console.WriteLine("用时:" + swatch.Elapsed.ToString());
swatch.Restart();
//查找是否存在4;Where
if (list.Where(item => item.epc == "E22222").ToList().Count>0)
{
Console.WriteLine("Where ToList Find!");
}
else
{
Console.WriteLine("Where ToList not Find!");
}
swatch.Stop();
Console.WriteLine("用时:" + swatch.Elapsed.ToString());
swatch.Restart();
//list.Any() 一个元素满足条件的时候就返回true;也可以用来判断是否存在. 性能较低,推荐使用list.Exists();
if (list.Any(item => item.epc == "E22222"))
{
Console.WriteLine("list.Any() ok!");
}
else
{
Console.WriteLine("list.Any() not !");
}
swatch.Stop();
Console.WriteLine("用时:" + swatch.Elapsed.ToString());
//list.All() 判断所有元素是不是都满足某个条件,性能低. 一般用来判断元素内容的长度等是否符合;
List<string> list1 = new List<string> { "01", "03" };
List<string> list2 = new List<string> { "01", "02", "03", "02", "05" };
var ls= list2.Except(list1);//差集
var ls2 = list2.Intersect(list1);//交集
var ls3 = list1.Union(list2);//并集,合并且去重后的
//交集
var ls4 = list2.Where(a => list1.Any(b => b.ToUpper() == a.ToUpper())).ToList();
//差集
var ls5 = list1.Where(a => !list2.Any(b => b.ToLower() == a.ToLower())).ToList();//list1元素少,为空
//差集
var ls6 = list2.Where(a => !list1.Any(b => b.ToLower() == a.ToLower())).ToList();
}
}
public class epcData
{
public string ip;
public string epc;
public epcData(string ipaddress,string tagEPC)
{
ip = ipaddress;
epc = tagEPC;
}
}
public class Compare : IEqualityComparer<epcData>
{
bool IEqualityComparer<epcData>.Equals(epcData x, epcData y)
{
if(x.ip==y.ip&&x.epc==y.epc)
{
return true;
}
else
{
return false;
}
}
int IEqualityComparer<epcData>.GetHashCode(epcData obj)
{
//-----------------------GetHashCode部分,网上有些文章说得云里雾里的,还把意思说反了,这里以实测结果为准,实测!!!------------------------------//
//1.Hash值的效率比引用类型判断是否相等的函数Equals更快,所以被用来辅助判断键值对集合的键值是否已经存在。
//2.IEqualityComparer内部会在使用 Equals 前先使用 GetHashCode 方法判断两个值是否相等;如果不相等就没有再判断Equals了.
//3.这里需要obj.ToString()之后再GetHashCode , 或者是直接写return 1返回相同的值,值相同的时候,才会使用Equals判断.
return 0;
//return obj.ToString().GetHashCode();
}
}
//采用了泛型委托的方式,实现只需要定义一个类实现IEqualityComparer<TSource>接口,Equals、GetHashCode的实现,由传入的委托方法决定,接下来就简单了
//var newList3 = list.Distinct(new LambdaComparer<epcData>((a, b) => a.ip == b.ip && a.epc == b.epc, obj => obj.ToString().GetHashCode())).ToList();
public class LambdaComparer<T> : IEqualityComparer<T>
{
private readonly Func<T, T, bool> _lambdaComparer;
private readonly Func<T, int> _lambdaHash;
public LambdaComparer(Func<T, T, bool> lambdaComparer)
: this(lambdaComparer, EqualityComparer<T>.Default.GetHashCode)
{
}
public LambdaComparer(Func<T, T, bool> lambdaComparer, Func<T, int> lambdaHash)
{
if (lambdaComparer == null)
throw new ArgumentNullException("lambdaComparer Null");
if (lambdaHash == null)
throw new ArgumentNullException("lambdaHash Null");
_lambdaComparer = lambdaComparer;
_lambdaHash = lambdaHash;
}
public bool Equals(T x, T y)
{
return _lambdaComparer(x, y);
}
public int GetHashCode(T obj)
{
return _lambdaHash(obj);
}
}
}