List<MyObject> Contains
本文关键字:Contains gt MyObject List lt | 更新日期: 2023-09-27 18:11:21
检查列表中是否存在一个条目的最快方法(编码方面)是什么?MyObject有两个属性
public class Name
{
public string FirstName{ get; set; }
public string LastName { get; set; }
}
那么我有另一个类,像这样:
public class Foo
{
private List<Name> Names : new List<Name>();
public List<Name> Names { get; set; }
public bool Contains(Name x)
{
if (x == null)
return false;
>>> Navigate || Equals || Linq.Contains
>>> What's the easiest way to do this?
}
}
最快的List是O(n)
查找速度和O(1)
插入速度:
至少一个
Names.Any(n=> x.FirstName == n.FirstName && x.LastName == n.LastName)
Exactly One:
Names.Count(n=> x.FirstName == n.FirstName && x.LastName == n.LastName) == 1
Any()更快,因为它在找到Name的第一个实例时短路。Count每次都在列表中搜索Name的所有实例。
相反,您可以使用Collection(例如HashSet, Dictionary等),其中查找操作是O(1)
。但是,集合不具有与列表相同的属性。注意,Hashset<string>
将名称存储为类似FirstName + (delimeter) + LastName
的东西,这比您拥有的任何其他选项都要快。
您也可以使用SortedList,其中查找速度为O(log(n))
。但是,在排序列表中插入元素是O(nlog(n))
,因为每次插入后必须保持列表的排序。
我会说linq .Any很简单http://msdn.microsoft.com/en-us/library/system.linq.enumerable.any.aspx
Names.Any(n=> n==x)
使用Linq
应该更容易阅读。下面是使用Any
的示例。
public bool Contains(Name x)
{
if (x == null)
return false;
return this.Names.Any(item => item.FirstName == x.FirstName && item.LastName == x.LastName);
}
建议:如果您的list
中的项目应该是唯一的,那么您可以使用System.Collections.Generic.HashSet
和使用System.Linq.Enumerable.Contains
..
您可能想要比较以下代码的Contains
和Any
方法的性能:
partial class Foo {
class NameComparer: IComparer<Name> {
public int Compare(Name x, Name y) {
return
object.ReferenceEquals(x, y)
||y.LastName==x.LastName&&y.FirstName==x.FirstName?0:~0;
}
public static readonly NameComparer Default=new NameComparer();
}
public bool Any(Name x) {
return
Names.Any(
y => object.ReferenceEquals(x, y)
||y.LastName==x.LastName&&y.FirstName==x.FirstName);
}
public bool Contains(Name x) {
return Names.BinarySearch(x, NameComparer.Default)>~0;
}
}