对List.Sort的简单研究

本文通过实例演示了如何使用C#中的IComparer接口为List<T>类型的数据进行自定义排序,特别是针对时间倒序的场景,并探讨了排序方法对性能的影响。

最近一直忙着修改项目中的bug,特别是一些绑定的列表排序,因为是中途加入的,所以我一般不改变别人的存储过程或者类方法,只在需要的时候帮其排序一下,不过非常郁闷。。。。。。

 

为什么呢???存储过程用得是传入Where后的条件,然后拼接一个sql语句- -

一开始我以为只要在拼接后面加入order by就可以了,谁知道。。。order by的条件也是传入的 再次晕!!!

好吧,那我在绑定的时候弄排序吧。。。先前一直用DataView的Sort,比较方便,只要指定排序的列名就ok了,谁知道。。。他绑定的是List<T>。。。。。怎么办。。。现在没有用过,看了下Sort方法,参数是IComparer<T> comparer,郁闷,先前一直没接触过,所以在家慢慢研究了一下,发觉很神奇,这里简单介绍下,希望大家也能帮我解答一下。

先设定个类MyClass

 

ContractedBlock.gifExpandedBlockStart.gifCode
public class MyClass
ExpandedBlockStart.gifContractedBlock.gif    
{
        
private int userID;

        
public int UserID
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return userID; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set { userID = value; }
        }

        
private string userName;

        
public string UserName
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return userName; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set { userName = value; }
        }

        
private DateTime addTime;

        
public DateTime AddTime
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return addTime; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set { addTime = value; }
        }


        
public MyClass(int userID, string userName, DateTime addTime)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this.userID = userID;
            
this.userName = userName;

            
this.addTime = addTime;
        }



    }

 

好,我现在要按照时间来倒序

因为第一次用IComparer 接口,所以做的简单点

写一个类,继承IComparer接口,实现Compare方法

 

ContractedBlock.gifExpandedBlockStart.gifMyClassComparer
public class MyClassComparer : IComparer<MyClass>
ExpandedBlockStart.gifContractedBlock.gif    
{
      

ContractedSubBlock.gifExpandedSubBlockStart.gif        
IComparer 成员#region IComparer<MyClass> 成员

        
//比较两个对象并返回一个值,指示一个对象是小于、等于还是大于另一个对象。
        public int Compare(MyClass x, MyClass y)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
//因为是倒序,所以如果x的时间大于y的时间,返回负数
            if (x.AddTime > y.AddTime)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return -1;
            }

            
else if (x.AddTime < y.AddTime)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return 1;
            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return 0;
            }

            
        }


        
#endregion

    }

 

测试一下:

 

ContractedBlock.gifExpandedBlockStart.gifProgram
class Program
ExpandedBlockStart.gifContractedBlock.gif    
{
        
static void Main(string[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            

            List
<MyClass> userList = new List<MyClass>();

            
for (int i=0; i < 50; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                userList.Add(
new MyClass(i, "James" + i.ToString(), DateTime.Now.AddHours(i)));
            }

            
            DateTime nowTime, endTime;

            nowTime 
= DateTime.Now;
            
foreach (MyClass c in userList)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                Console.WriteLine(c.UserID 
+ ":" + c.UserName + " at " + c.AddTime);
            }

            System.Data.DataSet ds 
= new System.Data.DataSet();
            
            endTime 
= DateTime.Now;

            Console.WriteLine(
"未排序所用时间" + (endTime.Ticks - nowTime.Ticks));

            nowTime 
= DateTime.Now;

            userList.Sort(
new MyClassComparer());
            
foreach (MyClass c in userList)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                Console.WriteLine(c.UserID 
+ ":" + c.UserName + " at " + c.AddTime);
               
            }


            endTime 
= DateTime.Now;

            Console.WriteLine(
"排序所用时间" + (endTime.Ticks - nowTime.Ticks));

         
            Console.ReadLine();
        }

    }

 

测试成功,不过一开始我在MyClasComparer.Comparer方法里没有设定等于,所以排序的时候会提示错误,而且排序的时候也不正确,看了IComparer接口对于Comparer的说明(MSDN):比较两个对象并返回一个值,指示一个对象是小于、等于还是大于另一个对象。 不太明白它是如何做到排序的,只是返回个int值就可以了。。。。

排序的时候,使用userList.Sort(new MyClassComparer().Compare);也是一样的效果,我知道ICompare使用了委托,所以在这里不需要我们来传参数了,我在Compare方法中设了断点,想看看是不是每次都是循环排序,跟踪下来是循环进行排序的,然后我想看看性能,奇怪的事情出现了。。。。

10个对象的时候,排序时间<未排序时间

100个对象的时候,排序时间>未排序时间

 

这个有点不太明白了,希望大家能帮我解答一下

 

下面是50个对象时的截图

 

很奇怪,排序所用时间比未排序还要短。。。为什么啊

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值