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<MyObject> Contains

最快的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(例如HashSetDictionary等),其中查找操作是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 ..

您可能想要比较以下代码的ContainsAny方法的性能:

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;
    }
}