Sorting ArrayList Containing User Defined Types

原创 2004年08月24日 20:04:00
Introduction:

We all know about ArrayList and its functionlity, it is the dynamic array of the .Net Framework, where you can add, delete, search & sort objects in it. The issue we will descuss in this article is Sorting ArrayList.

Define the issue:

The problem is stated in MSDN in the definition of the Sort method it says: "Sorts the elements in the entire ArrayList using the IComparable implementation of each element". which means that any object in the ArrayList that you wish to sort must implement the IComparable interface. I think most of .Net Framework implements the IComparable interface like Int32,Int16...,String,Decimal etc.... but what about our own types??!! the Classes and structures we build ourselvs?? do we still able to sort them??!!! yes we can do that, but note that those will be complex type, which mean that you have to know what is the parameter you are going to use to sort your own defined types, and this what we are going to see in the next sections.

Note: :if you tried to sort and array or an ArrayList that is containing your defined type, and this type do not implement the IComparable interface, you will get an exception.

IComparable interface:

By looking in the MSDN, I found the IComparable interface has only one method, CompareTo which take only one parameter of type object, which mean it can accept any type, and returns an integer which mean the following:

  • Less than zero if this instance is less than obj.
  • Zero if this instance is equal to obj.
  • Greater than zero if this instance is greater than obj.

So all we have to do when building our own type is to implement the IComparable interface example:

public class Employee : System.IComparable
{
 //....code
 public int CompareTo(object obj)
 {
  //..implementation
 }
}

Now we will see how to implement the IComparable interface. First we will create a new class called Employee. This class will contain Employee name,ID,salary & department name, at the begining we will sort the according to Employee ID then we will see how to implement a parametrized sorting, so can sort by name and salary or anything else. So let's see the Empolyee Class

class Empolyee : System.IComparable
{
 private string m_EmpName;
 private string m_EmpDept;
 private int m_EmpID;
 private decimal m_EmpSalary;
  
 public Employee(int id, string name,string dept)
 {
  m_EmpID = id;
  m_EmpName = name;
  m_EmpDept = dept;
  m_EmpSalary = 0.0M;
 }
 public string Name
 {
  get{return m_EmpName;}
  set{m_EmpName=value;}
 }
 public string Department
 {
  get{return m_EmpDept;}
  set{m_EmpDept=value;}
 }
 public int ID
 {
  get{return m_EmpID;}
  set{m_EmpID=value;}
 }
 public decimal Salary
 {
  get{return m_EmpSalary;}
  set{m_EmpSalary=value;}
 }
 /// 
 /// Less than zero if this instance is less than obj. 
 /// Zero if this instance is equal to obj. 
 /// Greater than zero if this instance is greater than obj. 
 ///
 ///
 /// This method uses the predefined method Int32.CompareTo 
 ///
 public int CompareTo(object obj)
 {
  if(!(obj is Employee))
   throw new InvalidCastException("This object is not of type Employee");
  
  Employee emp = (Employee)obj;
  //no need to rewrite the code again, we have int.CompareTo ready to use
  return this.ID.CompareTo(emp.ID);
 }
}

As you see in that class, it is easy to implement the IComparable interface. and also I didn't write the code myself, I used the Int32.CompareTo method, cause it is already implemented to compare integers, but if you wish you can write it yourself, it will be like this:

if(this.ID < emp.ID)
 return -1;
else if(this.ID==emp.ID)
 return 0;
else
 return 1;

That was easy wasn't it?

Now when you add you Empolyees to an ArrayList, you can sort this ArrayList with no porblems, better than implement a sort algorithm to sort your own types.

What is Next:

Suppose you want to make several option for sorting!! like sorting by name or by salary??!! The implementation is too easy and simple, the solution I made is to create an enumiration with the values of sorting options:

public enum SortBy{ID,NAME,SALARY}

then I created a static property of type SortBy enum in my Employee class:

private static SortBy m_SortBy = SortBy.NAME;
public static SortBy SortBy
{
 get{return m_SortBy;}
 set{m_SortBy=value;}
}

then I modified the CompareTo method this way:

public int CompareTo(object obj)
{
 if(!(obj is Employee))
  throw new InvalidCastException("This object is not of type Employee");
 
 Employee emp = (Employee)obj;
 switch(m_SortBy)
 {
  case ArrayListSortingDemo.SortBy.ID:
   return this.ID.CompareTo(emp.ID);
  case ArrayListSortingDemo.SortBy.NAME:
   return this.Name.CompareTo(emp.Name);
  case ArrayListSortingDemo.SortBy.SALARY:
   return this.Salary.CompareTo(emp.Salary);
  default:
   goto case ArrayListSortingDemo.SortBy.NAME;
 }
  
}

Just simple switch..case statement.

and before calling the ArrayList.Sort, I set the Property Employee.SortBy to the sort value option.

I built a simple form that uses the Employee Class and store objects from it in the ArrayList, I'm using a combo box to select sort option, then I set the sort option and call the ArrayList.Sort method

the results is displayed in a ListBox

mosessaur_ArrayListSortScree.gif 

Download the code

You can do more complex sort options,but here I want to explain to core of sort in the Arrays and ArrayList.

Wish you all the best

Android DataBinding错误记录

&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt; &amp;lt;layout xmlns:androi...
  • lihenair
  • lihenair
  • 2018-03-06 23:02:11
  • 131

关于C++中报Error:new types may not be defined in a return type问题

#include using namespace std;class Clock{      public:           Clock(int NewH,int NewM,int NewS); ...
  • laishegnzhen
  • laishegnzhen
  • 2010-06-01 23:36:00
  • 3924

discards qualifiers || new types may not be defined in a return type|| shadows a parameter

在C/C++重编译错误new types may not be defined in a return type TcpServer.cpp:29: error: new typ...
  • scut1135
  • scut1135
  • 2013-11-14 23:10:10
  • 1575

VB6.0在编译declare语句时报错,无法通过

是这样的,我做了一个DLL文件,然后在exe工程里的(general)做declare,但编译时即不通过,报如下错误: compile error:      constants,fixed-le...
  • u012187684
  • u012187684
  • 2014-03-08 20:39:57
  • 778

MS SQL Server 2008 新特性 - User-Defined Table Type 实现将.NET DataTable作为参数传入数据库

在MS SQL Server 2008之前,我们无法直接在.NET程式中直接将一个DataTable当作参数传入到存储过程.现在在MS SQL Server 2008可以完全实现这个功能了!其中完成这...
  • lost_painting
  • lost_painting
  • 2011-07-05 20:02:57
  • 4300

C++程序报错new types may not be defined in a return type?

C++程序报错new types may not be defined in a return type?类声明或定义结束时没有加;符号class A { }; 最后要加一个分号...
  • qq_15437667
  • qq_15437667
  • 2017-08-24 11:52:49
  • 433

StoryBoard之User Defined Runtime Attributes的使用

User Defined Runtime Attributes 是一个不被看重但功能非常强大的的特性,它能够配置一些你在interface builder 中不能配置的属性。当你希望在IB中作尽可能多...
  • u013263917
  • u013263917
  • 2015-11-02 14:50:50
  • 1789

User Defined Runtime Attributes在xib文件中给组件添加圆角

User Defined Runtime Attributes 是一个不被看重但功能非常强大的的特性,它能够配置一些你在interface builder 中不能配置的属性。当你希望在IB中作尽可能多...
  • l863784757
  • l863784757
  • 2015-04-13 15:28:56
  • 2948

Failed to set () user defined inspected property on (UIButton): [<UIButton 0x7fe5586efeb0> setValue:

Failed to set () user defined inspected property on (UIButton): [ setValue:forUndefinedKey:]: this c...
  • qq_32010299
  • qq_32010299
  • 2016-04-22 15:47:53
  • 2158

xib中User Defined Runtime Attributes使用

1、一般的控件直接使用layer.cornerRadius即可 2、UIImageView还需要设置layer.maskToBounds...
  • xttxqjfg
  • xttxqjfg
  • 2017-04-14 13:07:17
  • 570
收藏助手
不良信息举报
您举报文章:Sorting ArrayList Containing User Defined Types
举报原因:
原因补充:

(最多只允许输入30个字)