总结:查找一个对象在列表中位置的方法

  查找一个对象 在对象列表中的位置是日常项目开发过程中最最常用的。大慨总结了一下,有3个常用的方法。

  

public class Test
{
        public string Name
        {
            get;
            set;
        }
}

 

一、最最常用的 依次循环查找法

      private int LoopMethod()
        {
            for (int i =0; i < testList.Count; i++)
            {
                Test t = testList[i];
                if (t.Name.Equals(this.findName))
                {
                    return i;
                }
            }
            return -1;
        }



 二、List.IndexOf 方法

        private int IndexOfMethod()
        {
            Test find = new Test()
            {
                Name = this.findName
            };
            int i = testList.IndexOf(find);
            return i;
        }

 

   同时需要将 Test.Equals方法进行重写

    public class Test
    {
        public string Name
        {
            get;
            set;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }

            if (!(obj is Test)) return false;

            return string.Equals(this.Name, (obj as Test).Name);
        }
    }

 

 三、Linq方法

  

        private int LinqMethod()
        {
            int index = testList.FindIndex(test => test.Name.Equals(this.findName));
            return index;
        }

  

 

 

 总结:

  经过一些代码测试发现(第一种、第二种、第三种):

     第一种方法的查询速度最快,再次是 Linq查询方法,再就是List.IndexOf方法

     测试代码如下:

            List<Test> testList;
            string findName = "";
            testList = new List<Test>();
            for (int i = 0; i < 10000; i++ )
            {
                string name = Guid.NewGuid().ToString();
                if (i == 9998)
                {
                    findName = name;
                }
                Test t = new Test()
                {
                    Name = name
                };
                testList.Add(t);
            }

 

 

            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();
            int index = -1;
            for (int k = 0; k < 100; k++)
            {
                index = LoopMethod();
            }
            watch.Stop();
            Console.WriteLine("LoopMethod: " + index.ToString() + ": " + watch.ElapsedMilliseconds.ToString());

            System.Diagnostics.Stopwatch watchIndex = new System.Diagnostics.Stopwatch();
            watchIndex.Start();
            for (int k = 0; k < 100; k++)
            {
                index = IndexOfMethod();
            }
            watchIndex.Stop();
            Console.WriteLine("IndexOfMethod : " + index.ToString() + ": " + watchIndex.ElapsedMilliseconds.ToString());

            System.Diagnostics.Stopwatch watchLinq = new System.Diagnostics.Stopwatch();
            watchLinq.Start();
            int res = -1;
            for (int k = 0; k < 100; k++)
            {
                res = LinqMethod();
            }
            watchLinq.Stop();
            Console.WriteLine("LinqMethod : " + res.ToString() + ": " + watchLinq.ElapsedMilliseconds.ToString());

 

 

运行结果:

  LoopMethod: 9998: 99
     IndexOfMethod : 9998: 157
     LinqMethod : 9998: 114

 经简单分析:

  LoopMethod 耗时主要在依次循环中

     IndexOfMethod 耗时主要在 Equals 方法中。

     Linq方法 耗时主要在委托中

经过反编译发现:这3种方法的原理都是依次查询。

  IndexOf方法:

public int IndexOf(T item)
{
    return Array.IndexOf<T>(this._items, item, 0, this._size);
}

 
public static int IndexOf<T>(T[] array, T value, int startIndex, int count)
{
    if (array == null)
    {
        throw new ArgumentNullException("array");
    }
    if ((startIndex < 0) || (startIndex > array.Length))
    {
        throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
    }
    if ((count < 0) || (count > (array.Length - startIndex)))
    {
        throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
    }
    return EqualityComparer<T>.Default.IndexOf(array, value, startIndex, count);
}

 
internal virtual int IndexOf(T[] array, T value, int startIndex, int count)
{
    int num = startIndex + count;
    for (int i = startIndex; i < num; i++)
    {
        if (this.Equals(array[i], value))
        {
            return i;
        }
    }
    return -1;
}

 

 

      Linq 方法核心:  

public int FindIndex(Predicate<T> match)
{
    return this.FindIndex(0, this._size, match);
}

 

 public int FindIndex(int startIndex, int count, Predicate<T> match)
{
    if (startIndex > this._size)
    {
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
    }
    if ((count < 0) || (startIndex > (this._size - count)))
    {
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
    }
    if (match == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
    }
    int num = startIndex + count;
    for (int i = startIndex; i < num; i++)
    {
        if (match(this._items[i]))
        {
            return i;
        }
    }
    return -1;
}

 

 


     

 

转载于:https://www.cnblogs.com/foolishfox/archive/2010/08/02/1790178.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值