任意对象数组ArrayList的排序法(可自定义排序字段、排序方向)

ArrayList可以用来组合任何的对象,但其默认的排序是按对象本身值来排序,而不是应用自定义的,因此需要重新修改ArrayList的Sort方法的IComparer接口实现。以下是重新写的IComparer的实现,用了类型反射以做到能适合所有类的排序

性能测试:(仅供参考)
配置:PIII 733  384M内存
         Windows2000SP4   .net FrameWork 1.1.4322 SP1

ArrayList容纳100个对象,排序时间大约10~20毫秒
ArrayList容纳1000个对象,排序时间大约100毫秒左右
ArrayList容纳10000个对象,排序时间大约1200~1600毫秒



代码:
ReverserClass
实现IComparer接口的自定义类,其中定义了ArrayList包含的对象的类型type和需要排序的类型的字段name
public class ReverserClass : IComparer  {
        Type type 
= null;
        
string name = string.Empty;
        
string direction = "ASC";
        
public ReverserClass(Type type, string name, string direction) {
            
this.type = type;
            
this.name = name;
            
if(direction.Equals("DESC"))
                
this.direction = "DESC";
        }


         
int IComparer.Compare( object x, object y )  {
             
object x1 = this.type.InvokeMember(this.name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty, null, x, null);
             
object y1 = this.type.InvokeMember(this.name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty, null, y, null);
             
if(direction.Equals("DESC"))
                 Swap(
ref x1, ref y1);
             
return( (new CaseInsensitiveComparer()).Compare( x1, y1 ));
        }


        
void Swap(ref object x, ref object y ) {
            
object temp = null;
            temp 
= x;
            x 
= y;
            y 
= temp;
        }


    }


测试代码
UserClass
public class UserClass {
    
protected string _name;
    
protected int _age;
    
protected string _address;

    
public UserClass(string _name, int _age, string _address) {
        
this._name = _name;
        
this._age = _age;
        
this._address = _address;
    }


    
public string Name {
        
get return _name; }
        
set { _name = value; }
    }


    
public int Age {
        
get return _age; }
        
set { _age = value; }
    }


    
public string Address {
        
get return _address; }
        
set { _address = value; }
    }


}

main
其中ReverserClass reverser = new ReverserClass(user.GetType()"Name"); 中的要传递ArrayList数组中的对象的类型和需要作为排序依据的字段名称!
        static void Main(string[] args)
        
{
            UserClass user;
            ArrayList ar 
= new ArrayList();
            user 
= new UserClass("1"1"1");
            ar.Add(user);
            user 
= new UserClass("9"9"9");
            ar.Add(user);
            user 
= new UserClass("4"4"4");
            ar.Add(user);
            user 
= new UserClass("3"3"3");
            ar.Add(user);
            user 
= new UserClass("6"6"6");
            ar.Add(user);
            
            Console.WriteLine();
            ReverserClass reverser 
= new ReverserClass(user.GetType(), "Name", "DESC");
            ar.Sort(reverser);
            Console.WriteLine();


        }
posted @ 2004-12-30 16:57 dannyr|一个都不能少! 阅读(8842) 评论(5)  编辑 收藏 网摘 所属分类: .Net技术

  回复  引用    
#1楼 2004-12-30 23:13 | 中国寝具网 [未注册用户]
兄弟你的方法好像还不太完善,如果两个类的Name一样,每排一次他们在数组中出现的位置就变化一下。位置不稳定。
  回复  引用  查看    
#2楼 [楼主]2004-12-31 09:10 | dannyr|一个都不能少!      
这里直接使用Array.Sort,执行的是不稳定排序;亦即,如果两元素相等,则其顺序可能不被保留
  回复  引用  查看    
#3楼 2004-12-31 09:40 | umlchina      
办法不错
不过对于任何两个对象比较都需要用反射的方式,对性能的影响大,尤其是在arraylist中元素较多的时候.
虽然灵活,可还不如自己具体写排序字段比较来的实在
  回复  引用  查看    
#4楼 [楼主]2004-12-31 10:16 | dannyr|一个都不能少!      
对性能的确有影响,数组包含10000个对象时候排序需要花1.5秒左右的时间(我的电脑配置是PIII 733),不过我认为小数据量排序还是可以满足需要的,大数据量排序我认为应该在数据库获取数据的时候就应该排好序了。
  回复  引用    
#5楼 2007-06-18 09:15 | cc [未注册用户]
ccc




标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2004-12-31 10:32 编辑过
Google站内搜索


China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!

相关文章:

相关链接: