Article Options
Premium Sponsor
Premium Sponsor

 »  Home  »  Windows Development  »  Sorting objects using IComparer and IComparable Interfaces
Sorting objects using IComparer and IComparable Interfaces
by Ashish Jaiman | Published  03/04/2002 | Windows Development | Rating:
Ashish Jaiman

Ashish works as a Sr. Software Developer with Lexign Inc., an end-to-end trusted electronic transaction management software provider (http://www.lexign.com).

Ashish has 6 years of experience in designing and developing distributed systems, server technologies and web based software applications using Microsoft technologies, Java, XML and .NET. He holds MCSD (Microsoft Certified Software Developer) and SCJP (Sun Certified Java Programmer) certifications.

Contact Ashish at jaimanalwar@yahoo.com or ashish.jaiman@lexign.com.

 

View all articles by Ashish Jaiman...
Sorting objects using IComparer and IComparable Interfaces

Article source code: sorting.zip

The System.Collections namespace contains interfaces and classes that define various collections of objects, such as lists, queues, bit arrays, hashtables and dictionaries. You can use a collection to store objects, some collection implementations would sort your objects by default when they are added to the collection and some would just add them in sequence. Once the objects are added to a collection if a custom ordered list (custom sorting) of stored objects is required IComparer interface form System.Collections namespace and IComparable interface from System namespace comes in handy.

An ArrayList is a Class that implements the IList interface using an array whose size is dynamically increased as required. ArrayList.Sort method sorts the elements in the ArrayList.

Details of ArrayList.Sort method (Overload List) (check MSDN for more info)

  • Sorts the elements in the entire ArrayList using the IComparable implementation of each element.

  • [Visual Basic] Overloads Overridable Public Sub Sort()
    [C#] public virtual void Sort();
  • Sorts the elements in the entire ArrayList using the specified comparer.

  • [Visual Basic] Overloads Overridable Public Sub Sort(IComparer)
    [C#] public virtual void Sort(IComparer);
  • Sorts the elements in a section of ArrayList using the specified comparer.

  • [Visual Basic] Overloads Overridable Public Sub Sort(Integer, Integer, IComparer)
    [C#] public virtual void Sort(int, int,IComparer);

Following is an example to sort an ArrayList object that stores CEmp object by four different ways. The first sample uses IComparer interface implemented by a nested class (CMySort) that is used for custom sorting. The second example uses the IComparable interface implemented by CEmp class and a public property to set for custom sorting The CEmpdata class reads an XML document and creates objects of CEmp class and stores them in an ArrayList. The ArrayList then is sorted by FirstName Ascending, FirstName Descending, LastName Ascending and LastName Descending as defined by the enum.

XML Document

<employees>
    <employee>
        <firstname>ashish</firstname>
        <lastname>jaiman</lastname>
    </employee>
    <employee>
        <firstname>jaya</firstname>
        <lastname>pandey</lastname>
    </employee>
    <employee>
        <firstname>neeraj</firstname>
        <lastname>jaiman</lastname>
    </employee>
    <employee>
        <firstname>ashutosh</firstname>
        <lastname>sharma</lastname>
    </employee>
    <employee>
        <firstname>zerman</firstname>
        <lastname>billingslea</lastname>
    </employee>
    <employee>
        <firstname>bernd</firstname>
        <lastname>burkhardt</lastname>
    </employee>
    <employee>
        <firstname>sanjeev</firstname>
        <lastname>bhutt</lastname>
    </employee>
    <employee>
        <firstname>li</firstname>
        <lastname>li</lastname>
    </employee>
</employees>

VB.Net implementation of sorting by using specified Comparer
Imports System
Imports System.Collections
Imports System.Xml

Public Class CEmpData

    Public Enum enuSortOrder
        FirstNameAsc = 0
        FirstNameDesc = 1
        LastNameAsc = 2
        LastNameDesc = 3
    End Enum

    Private ArrEmp As ArrayList
    Private objEmp As CEmp

    Public Sub New()
        InitializeData()
    End Sub

    Private Sub InitializeData()
        Dim xmldoc As New XmlDocument()
        Dim node As XmlNode
        Dim objEmp As CEmp
        xmldoc.Load("empdata.xml")
        ArrEmp = New ArrayList()
        For Each node In xmldoc.DocumentElement.ChildNodes
            objEmp = New CEmp()
            objEmp.FName = node.SelectSingleNode("firstname").InnerText
            objEmp.LName = node.SelectSingleNode("lastname").InnerText
            ArrEmp.Add(objEmp)
        Next
    End Sub

    Public Function GetSortedEmp_
        ByVal xlngSortOrder As enuSortOrderAs String
        ArrEmp.Sort(New CMySort(xlngSortOrder))
        GetSortedEmp = GetData(ArrEmp)
    End Function

    Private Function GetData(ByVal xArrEmp As ArrayListAs String
        Dim intCount As Integer
        Dim strEmpData As String
        For intCount = 0 To xArrEmp.Count - 1
            strEmpData = strEmpData & CType(xArrEmp(intCount), _
                CEmp).FName & Chr(9& CType(xArrEmp(intCount), _
                CEmp).LName & Chr(13)
        Next
        GetData = strEmpData
    End Function

    Class CMySort
        Implements IComparer
        Dim lngCompType As Integer
        Sub New(ByVal xlngCompType As Integer)
            lngCompType = xlngCompType
        End Sub
        Public Function Compare(ByVal x As Object_
            ByVal y As ObjectAs Integer Implements _
            System.Collections.IComparer.Compare
            Select Case lngCompType
                Case enuSortOrder.FirstNameAsc
                    Compare = CType(xCEmp).FName < CType(yCEmp).FName
                Case enuSortOrder.FirstNameDesc
                    Compare = CType(xCEmp).FName > CType(yCEmp).FName
                Case enuSortOrder.LastNameAsc
                    Compare = CType(xCEmp).LName < CType(yCEmp).LName
                Case enuSortOrder.LastNameDesc
                    Compare = CType(xCEmp).LName > CType(yCEmp).LName
                Case Else
                    Compare = CType(xCEmp).FName < CType(yCEmp).FName
            End Select
        End Function
    End Class
End Class

Public Class CEmp

    Private mstrFName As String
    Private mstrLName As String

    Public Property FName() As String
        Get
            FName = mstrFName
        End Get
        Set(ByVal Value As String)
            mstrFName = Value
        End Set
    End Property

    Public Property LName() As String
        Get
            LName = mstrLName
        End Get
        Set(ByVal Value As String)
            mstrLName = Value
        End Set
    End Property

End Class
Generated using PrettyCode.Encoder

C# implementation of sorting by using specified Comparer
using System;
using System.Collections;
using System.Xml;

public class CEmpData
{
    public enum enuSortOrder{FirstNameAsc, FirstNameDesc,
                             LastNameAsc, LastNameDesc}

    private ArrayList ArrEmp;
    public CEmpData()
    {
        InitializeData();
    }
    private void InitializeData()
    {
        XmlDocument xmlDoc = new XmlDocument();
        CEmp objEmp;
        xmlDoc.Load("empdata.xml");
        ArrEmp = new ArrayList();
        foreach(XmlNode node in xmlDoc.DocumentElement.ChildNodes)
        {
            objEmp = new CEmp();
            objEmp.FName = node.SelectSingleNode("firstname").InnerText;
            objEmp.LName = node.SelectSingleNode("lastname").InnerText;
            ArrEmp.Add (objEmp);
        }
    }

    public string GetSortedEmp(int xlngSortOrder)
    {
        ArrEmp.Sort(new CMySort(xlngSortOrder));
        return GetEmpData(ArrEmp);
    }

    private string GetEmpData(ArrayList xArrEmp)
    {
        string strEmpData="";
        for (int intCount = 0;intCount < xArrEmp.Count;intCount++)
        {
            strEmpData = strEmpData + ((CEmp)xArrEmp[intCount]).FName +
                         "\t" + ((CEmp)xArrEmp[intCount]).LName  + "\n";
        }
        return strEmpData;
    }

    class CMySort:IComparer
    {
        private int intCompType;

        public CMySort(int sortOrder)
        {
            intCompType = sortOrder;
        }
        public int Compare(object x,object y)
        {
            switch(intCompType)
            {
                case (int)enuSortOrder.FirstNameAsc:
                    return ((CEmp)x).FName.CompareTo(((CEmp)y).FName);
                case (int)enuSortOrder.FirstNameDesc:
                    return ((CEmp)y).FName.CompareTo(((CEmp)x).FName);
                case (int)enuSortOrder.LastNameAsc:
                    return ((CEmp)x).LName.CompareTo(((CEmp)y).LName);
                case (int)enuSortOrder.LastNameDesc:
                    return ((CEmp)y).LName.CompareTo(((CEmp)x).LName);
                default:
                    return ((CEmp)x).FName.CompareTo(((CEmp)y).FName);
            }
        }
    }
}
using System;

public class CEmp
{
    private string mstrFName;
    private string mstrLName;

    public string FName
    {
        get
        {
            return mstrFName;
        }
        set
        {
            mstrFName = value;
        }
    }

    public string LName
    {
        get
        {
            return mstrLName;
        }
        set
        {
            mstrLName = value;
        }
    }
}

VB.Net implementation of sorting by using the IComparable interface
Imports System.Xml

Public Class CEmpData
    Private objEmp As CEmp
    Private ArrEmp As ArrayList

    Public Sub New()
        InitializeData()
    End Sub

    Private Sub InitializeData()
        Dim xmldoc As New XmlDocument()
        Dim node As XmlNode
        Dim objEmp As CEmp
        xmldoc.Load("empdata.xml")
        ArrEmp = New ArrayList()
        For Each node In xmldoc.DocumentElement.ChildNodes
            objEmp = New CEmp()
            objEmp.FName = node.SelectSingleNode("firstname").InnerText
            objEmp.LName = node.SelectSingleNode("lastname").InnerText
            ArrEmp.Add(objEmp)
        Next
    End Sub

    Public Function GetSortedEmp(ByVal xblnSortOrder As IntegerAs String
        CEmp.SortMethod = xblnSortOrder
        ArrEmp.Sort()
        GetSortedEmp = GetData(ArrEmp)
    End Function

    Private Function GetData(ByVal xArrEmp As ArrayListAs String
        Dim lngCount As Long
        Dim strEmpData As String
        For lngCount = 0 To xArrEmp.Count - 1
            strEmpData = strEmpData & xArrEmp(lngCount).fname & Chr_
                9& xArrEmp(lngCount).lname & Chr(13)
        Next
        GetData = strEmpData
    End Function
End Class


Imports System

Public Class CEmp
    Implements IComparable

    Public Enum enuSortOrder
        FirstNameAsc = 0
        FirstNameDesc = 1
        LastNameAsc = 2
        LastNameDesc = 3
    End Enum

    Private Shared mintSortOrder As Integer
    Private mstrFName As String
    Private mstrLName As String

    Public Property FName() As String
        Get
            FName = mstrFName
        End Get
        Set(ByVal Value As String)
            mstrFName = Value
        End Set
    End Property

    Public Property LName() As String
        Get
            LName = mstrLName
        End Get
        Set(ByVal Value As String)
            mstrLName = Value
        End Set
    End Property

    Public Function CompareTo_
        ByVal obj As ObjectAs Integer Implements IComparable.CompareTo
        Select Case mintSortOrder
            Case enuSortOrder.FirstNameAsc
                CompareTo = Me.FName < CType(objCEmp).FName
            Case enuSortOrder.FirstNameDesc
                CompareTo = Me.FName > CType(objCEmp).FName
            Case enuSortOrder.LastNameAsc
                CompareTo = Me.LName < CType(objCEmp).LName
            Case enuSortOrder.LastNameDesc
                CompareTo = Me.LName > CType(objCEmp).LName
            Case Else
                CompareTo = Me.FName < CType(objCEmp).FName
        End Select
    End Function

    Public Shared Property SortMethod() As enuSortOrder
        Get
            SortMethod = mintSortOrder
        End Get
        Set(ByVal Value As enuSortOrder)
            mintSortOrder = Value
        End Set
    End Property
End Class
Generated using PrettyCode.Encoder

C# implementation of sorting by using the IComparable implementation
using System;
using System.Collections;
using System.Xml;

public class CEmpData
{

    private ArrayList ArrEmp;
    public CEmpData()
    {
        InitializeData();
    }
    private void InitializeData()
    {
        XmlDocument xmlDoc = new XmlDocument();
        CEmp objEmp;
        xmlDoc.Load("empdata.xml");
        ArrEmp = new ArrayList();
        foreach(XmlNode node in xmlDoc.DocumentElement.ChildNodes)
        {
            objEmp = new CEmp();
            objEmp.FName = node.SelectSingleNode("firstname").InnerText;
            objEmp.LName = node.SelectSingleNode("lastname").InnerText;
            ArrEmp.Add (objEmp);
        }
    }

    public string GetSortedEmp(int xlngSortOrder)
    {    CEmp.SortOrder = xlngSortOrder;
        ArrEmp.Sort();
        return GetEmpData(ArrEmp);
    }

    private string GetEmpData(ArrayList xArrEmp)
    {
        string strEmpData="";
        for (int intCount = 0;intCount < xArrEmp.Count;intCount++)
        {
            strEmpData = strEmpData + ((CEmp)xArrEmp[intCount]).FName +
                         "\t" + ((CEmp)xArrEmp[intCount]).LName  + "\n";
        }
        return strEmpData;
    }
}

using System;

public class CEmp:System.IComparable
{
    public enum enuSortOrder{FirstNameAsc, FirstNameDesc,
                             LastNameAsc, LastNameDesc}
    public static int mintSortOrder;
    private string mstrFName;
    private string mstrLName;

    public string FName
    {
        get
        {
            return mstrFName;
        }
        set
        {
            mstrFName = value;
        }
    }

    public string LName
    {
        get
        {
            return mstrLName;
        }
        set
        {
            mstrLName = value;
        }
    }

    public static int SortOrder
    {
        get
        {
            return mintSortOrder;
        }
        set
        {
            mintSortOrder = value;
        }
    }

    public int CompareTo(object obj)
    {
        switch (mintSortOrder)
        {
            case (int)enuSortOrder.FirstNameAsc:
                return this.FName.CompareTo(((CEmp)obj).FName);
            case (int)enuSortOrder.FirstNameDesc:
                return (((CEmp)obj).FName).CompareTo(this.FName);
            case (int)enuSortOrder.LastNameAsc:
                return this.LName.CompareTo(((CEmp)obj).LName);
            case (int)enuSortOrder.LastNameDesc:
                return (((CEmp)obj).LName).CompareTo(this.LName);
            default:
                return this.FName.CompareTo(((CEmp)obj).FName);
        }
    }
}

How would you rate the quality of this article?
1 2 3 4 5
Poor Excellent
Tell us why you rated this way (optional):

Article Rating
The average rating is: No-one else has rated this article yet.

Article rating:3.72499999999997 out of 5
 80 people have rated this page
Article Score75387
Sponsored Links