Java集合如何实现排序?

Java中对集合进行排序的两种方法:

java集合的工具类Collections中提供了两种排序的方法,分别是:

  1. Collections.sort(List list)
  2. Collections.sort(List list,Comparator c)

 

 

 1)第一种称为自然排序:

参与排序的对象需实现comparable接口注:Interger和String不需要,java默认封装这个两个类实现了comparable接口,重写其compareTo()方法,方法体中实现对象的比较大小规则,示例如下: 

package test;

public class Emp implements Comparable {

    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Emp() {
        super();
    }
    public Emp(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Emp [name=" + name + ", age=" + age + "]";
    }
    @Override
    public int compareTo(Emp emp) {
        //  return this.age-emp.getAge();//按照年龄升序排序
            return this.name.compareTo(emp.getName());//换姓名升序排序
    } 
}
@Test  //测试
    public void testComparable(){
        List list = new ArrayList();

        list.add(new Emp(18, "tom"));
        list.add(new Emp(20,"jack"));
        list.add(new Emp(15,"rose"));
        list.add(new Emp(17,"jerry"));
        System.out.println("排序前:");
        for(Emp o : list){
             System.out.println(o);
        }
        Collections.sort(list);
        System.out.println("自然排序按age排序后:");
        for(Emp o : list) {
            System.out.println(o);
        }
    }

输出结果:

 

分析:第一种方法不够灵活,要求实体类(集合元素)必须实现comparable接口,并且定义比较规则,这样导致会增加耦合,不利于程序的扩展;如果在项目中不同的位置需要根据不同的属性调用排序方法时,需要反复修改比较规则(按name还是按age),二者只能选择其一,会起冲突,所以不建议使用这个构造方法。第二种就很好地解决了这个问题,在需要的地方,创建个内部类的实例,重写其比较方法即可。

 

2)第二种叫自定义排序:

方法一:自定义一个Comparator比较器对象,然后传入Collections.sort(List,Comparator)排序方法中进行排序自定义的比较器:

bean(实体类--集合元素):

public class Emp{
    private int age;
    private String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Emp(int age, String name) {
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

}

 测试代码如下:

import java.util.Comparator;
public class MyComparator implements Comparator<Emp>{
    @Override
    public int compare(Emp o1, Emp o2) {
        return o1.getAge()-o2.getAge();//根据传入的Emp的年龄age由小到大进行升序排序
    }
}
测试类:
@Test
public void testComparatorSortAge(){
   List list = new ArrayList();

   list.add(new Emp(18, "tom"));
   list.add(new Emp(20,"jack"));
   list.add(new Emp(15,"rose"));
   list.add(new Emp(17,"jerry"));
   System.out.println("排序前:");
   for(Emp o : list){
      System.out.println(o);
   }

   Collections.sort(list,MyComparator); 
  System.out.println("使用Comparator比较器自定义按age升序排序后:");
  for(Emp o : list){
    System.out.println(o);
  }
}

输出结果:

 

方法二:采用匿名内部的形式(推荐做法):

先new一个Comparator接口的比较器对象,同时实现compare()其方法;然后将比较器对象传给Collections.sort()方法的参数列表中,实现排序功能。

@Test
    public void testComparatorSortName(){
        List list = new ArrayList();

        list.add(new Emp(18, "tom"));
        list.add(new Emp(20,"jack"));
        list.add(new Emp(15,"rose"));
        list.add(new Emp(17,"jerry"));
        System.out.println("排序前:");
        for(Emp o : list){
            System.out.println(o);
        }

        Collections.sort(list, new Comparator() {

            @Override
            public int compare(Emp o1, Emp o2) {
          return o1.getName.compareTo(o2.getName);
            }
        });

        System.out.println("使用Comparator比较器自定义按name升序排序后:");
        for(Emp o : list){
            System.out.println(o);
        }
    }

输出结果:

 

 注:默认根据英文首字母大小比较排序,若首字母相同,则比较第二位字母大小,以此类推。

 

比较总结:

1.对于集合比较使用Collections.sort();
2.对于集合中的对象比较,需要指定比较逻辑,指定比较逻辑需要实现 Comparable接口并重写compareTo方法自定义逻辑。
3.对于需要临时改变比较规则,例如项目中存在多个场景调用不同的排序规则的情况时,需要使用Collections.sort(List,Comparator),采用回调方式重写Comparator接口的compare方法自定义逻辑。

参考文章:

1.https://blog.csdn.net/qq_43437465/article/details/89437637 

2.https://www.cnblogs.com/huangjinyong/p/9037588.html

posted @ 2021-07-07 17:04  向着阳光漫步  阅读(489)  评论(0编辑  收藏  举报