Java集合类中的排序

在开发过程中我们经常会遇到集合里的对象进行相应排序这种需求,对于这些乱序对象的排序我们最重要的就是做两件事情:第一,如何确定两个对象之间的大小关系;第二,依据怎样的方法对现有的对象排列。非常幸运的是,在Java程序语言里面已经给出了我们如何对一组已知大小关系的对象进行排列的解决方案,我们要做的就是完成第一件事情,即确定对象之间的大小关系,也就是说我们要想按着Java的方法对一组对象进行排列的话,我们就必须要保证这组对象是能够互相比较的。因此可以说我们指定比较规则确定对象的大小,Java提供排列方法进行高效排序。

3.6.1  让你的对象是可比较的
对于存储在集合里的自定义对象,要想对它们进行排序,我们只需要让它们实现相应的比较接口java.lang.Comparable,并且实现里面的比较方法compareTo(Object o),这个方法会有一个整数型的返回值,如果返回值大于0就表示当前的对象应该排在方法中传过来的对象的前面,如果返回值小于0就表示当前的对象应该排在方法中传过来的对象的后面,如果返回0就表示两个对象并列。然后我们只要调用公共类库中java.util.Collections这个类的sort(List list)方法,Java就会按照它的一套方法对list集合里面的对象排列先后次序。现在我们通过CompObj.java代码来了解一下自定义对象的排序是如何实现的。

import java.util.ArrayList;

import java.util.Collections;

public class CompObj implements Comparable

{

  int x;

  int y;

  public CompObj(int n1, int n2)

{

    x = n1;

    y = n2;

  }

  //打印该对象时会自动调用toString方法

  public String toString()

{

    return "[x = " + x + ", y = " + y + "]";

  }

  //赋写Comparable中的方法

  //定义比较规则,使CompObj对象可以互相比较

  public int compareTo(Object o) 

{

//注意把传入的参数转化成当前类型的对象

         CompObj co=(CompObj)o; 

      if(x!=co.x)

      {

            return x-co.x;

      }

      else

      {

            return y-co.y;

      }

   }

   public static void main(String[] args)

{

         ArrayList l=new ArrayList();

         l.add(new CompObj(3,2));

         l.add(new CompObj(1,3));

         l.add(new CompObj(1,2));

         System.out.println("before sort");

         for(int i=0;i<l.size();i++)

{

                System.out.println(l.get(i));

         }

         Collections.sort(l);

         System.out.println("after sort");

         for(int i=0;i<l.size();i++)

{

                System.out.println(l.get(i));

         }

  }

}

对于自定义的类CompObj,我们把它的一组对象存放在ArrayList里面,并且对它们进行排序。为了Collections.sort()方法可以正常运转,我们为CompObj这个类在compareTo(Object o)方法中定义了比较规则,因为sort()方法会去调用每个对象的compareTo()方法。这里我们定义的比较规则是:x值小的对象排在前面,如果x值相同那么y值小的对象排在前面。下面输出的结果:

before sort

[x = 3, y = 2]

[x = 1, y = 3]

[x = 1, y = 2]

after sort

[x = 1, y = 2]

[x = 1, y = 3]

[x = 3, y = 2]

根据我们的规则Collections.sort()方法做出了相应的排序,大家可以改变一下比较规则看看输出结果会有什么样的变化。

3.6.2  为你的对象定义比较器
在现实生活中我们会遇到这样一个问题就是同样一种类型的对象之间可能会按着不同的规则进行排序。比如说上面的例子中我们先比较x值的大小再比较y值的大小,那么如果我想先比较y值的大小再比较x值的大小怎么办呢?

Java里面给我们提供了一个比较器java.util.Comparator,我们只要在比较器中定义它所比较的两个对象之间的比较规则即可。然后同样调用公共类库中java.util.Collections这个类的sort(List list, Comparator c)方法,唯一的区别就是这个方法中多了一个比较器Comparator这个参数。让我们通过ObjComparator.java来了解一下是如何通过比较器实现集合里的对象排序的。

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

class ObjComparator implements Comparator

{

         public int compare(Object o1,Object o2)

{

              //注意把传入的参数转化成当前类型的对象

           CompObj1 co1=(CompObj1)o1;

           CompObj1 co2=(CompObj1)o2;                

           if(co1.y!=co2.y)

        {

                  return co1.y-co2.y;

}

           else

        {

                  return co1.x-co2.x;

         }

         }

}

public class CompObj1

{

  int x;

  int y;

  public CompObj1(int n1, int n2)

{

     x = n1;

     y = n2;

  } 

  //打印该对象时会自动调用toString方法

  public String toString()

{

     return "[x = " + x + ", y = " + y + "]";

  } 

  public static void main(String[] args)

{

         ArrayList l=new ArrayList();

         l.add(new CompObj1(3,2));

         l.add(new CompObj1(1,3));

         l.add(new CompObj1(1,2));

         System.out.println("before sort");

         for(int i=0;i<l.size();i++)

{

                System.out.println(l.get(i));

         }

         Collections.sort(l,new ObjComparator());

         System.out.println("after sort");

         for(int i=0;i<l.size();i++)

{

                System.out.println(l.get(i));

         }

  }

}

需要注意的是我们自定义的对象CompObj1根本不用实现什么java.uitl. Comparable接口,我们只要定义一个针对于该对象的比较器就可以完成排序的功能,这么做带来的好处就是,不仅可以针对一个类型的对象按着多种比较规则进行排序,而且我们完全的把对象的比较规则从对象的业务逻辑中抽离出来,达到了各司其职的目的。

以下是该程序的输出结果:

before sort

[x = 3, y = 2]

[x = 1, y = 3]

[x = 1, y = 2]

after sort

[x = 1, y = 2]

[x = 3, y = 2]

[x = 1, y = 3]

你可能感兴趣的:(java,生活)