java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Comparable和Comparator比较器

Java排序之Comparable和Comparator比较器详解

作者:nsnsttn

这篇文章主要介绍了Java排序之Comparable和Comparator比较器详解,Comparable<T>是内部比较器,Comparator<T>是外部比较器,最推荐使用Comparator<T>接口排序,Comparator提供静态方法很方便,推荐使用,需要的朋友可以参考下

Comparable和Comparator比较器

Comparable<T>和 Comparator<T>这俩接口经常被使用,这里介绍下这俩是什么以及怎么用

Comparable<T>和Comparator<T>一般都是用来排序对象的,

Comparable<T>是内部比较器,Comparator<T>是外部比较器,直接上代码看例子

1.Comparable<T>

Comparable<T>内部比较器,故那个类需要排序能力就实现它

使用方式

1.如果我们想让List<SortA>按一定方式排序,可以将SortA实现 Comparable<SortA>接口,重写compareTo(SortA s)方法

@Data
public class SortA implements Serializable, Comparable<SortA>{
    
  	 @ApiModelProperty("名字")
    private String name;
    @ApiModelProperty("年龄")
    private Integer age;
    
    
    //自定义排序规则
    @Override
    public int compareTo(SortA o) {
        return  this.age - o.getAge(); //升序
        //return this.age.compareTo( o.getAge()); //升序
        //return o.getAge() - this.age; //倒序
        //return o.getAge().compareTo(this.age); //倒序
        //return -1; //自然排序的倒序
        //return 1 或 0; //自然排序
    }
}
public class 排序 {
    public static void main(String[] args) {
		//创造数据
        List<SortA> listA = new ArrayList<>();
        SortA a1 = new SortA();
        a1.setName("a张三");
        a1.setAge(18);
        SortA a2 = new SortA();
        a2.setName("c李四");
        a2.setAge(16);
        SortA a3 = new SortA();
        a3.setName("b王五");
        a3.setAge(17);
        listA.add(a1);
        listA.add(a2);
        listA.add(a3);
		//调用方法
        testComparable(listA);
    }
  
    public static void testComparable(List<SortA> listA) {
        //排序方法Collections.sort(List<T> list);
        //内部使用 Arrays.sort(a, (Comparator) c);    
        //所以如果数据是是数组,可以直接用Arrays.sort(数据)来排序
        Collections.sort(listA);
        System.out.println("Comparable排序:" + listA);
        //Comparable排序:[SortA(name=李四, age=16), SortA(name=王五, age=17), SortA(name=张三, age=18)]
    }
}

2.Comparator<T>

我们可以发现Comparable<T>代码侵入性比较强,而且不够灵活,我们同一对象每次排序的规则不可能都一样,那么就可以外部比较器Comparator<T>

使用方式

2.1 Comparator可以不由SortA实现,可以实现一个SortAComparator排序类

//注意泛型是需要排序的类SortA
public class SortAComparator implements Comparator<SortA> {

    /**
     *	compare()和compareTo()很像,返回值参照compareTo(),o1相当于this
     */
    @Override
    public int compare(SortA o1, SortA o2) {
        int sort = o1.getAge() - o2.getAge();
        return sort;
    }
}

2.2 Comparable是一个函数式接口,所以可以使用匿名内部类或者Lambda表达式(常用)来实现

甚至jdk8以后Comparable<T>提供了很多static方法直接供我们使用

2.3 直接上代码

public class 排序 {
    public static void main(String[] args) {
		//创造数据
        List<SortA> listA = new ArrayList<>();
        SortA a1 = new SortA();
        a1.setName("a张三");
        a1.setAge(18);
        SortA a2 = new SortA();
        a2.setName("c李四");
        a2.setAge(16);
        SortA a3 = new SortA();
        a3.setName("b王五");
        a3.setAge(17);
        listA.add(a1);
        listA.add(a2);
        listA.add(a3);
		//调用方法
        testComparator(listA);
    }
    public static void testComparator(List<SortA> listA) {
        //外部比较器,实现Comparator接口
        //1.SortAComparator实现Comparator接口
        listA.sort(new SortAComparator());
        System.out.println(listA);
        //2.使用匿名内部类或Lambda,表达式
        listA.sort(new Comparator<SortA>() {
            @Override
            public int compare(SortA o1, SortA o2) {
                //年龄倒序
                return o2.getAge() - o1.getAge();
            }
        });
        //3.使用匿名内部类或Lambda或Comparator的静态方法"
        //3.1按照名字正序排序
       	listA.sort(Comparator.comparing(SortA::getName));
        System.out.println(listA);
        //3.2按照名字倒序排序
        listA.sort(Comparator.comparing(SortA::getName).reversed());
        System.out.println(listA);
        listA.sort(Comparator.comparing(SortA::getName,Comparator.reverseOrder()));
        System.out.println(listA);
    }
}

注意多条件情况!!

reversed和Comparator.reverseOrder()反转顺序的时机不同

Comparator.reverseOrder()会立即对此属性排序

reversed()会得到左边的结果后在排序

所以

Comparator.reverseOrder()是只针对当前属性的反转,

reversed()会使左边所有排序反转,注意这一点就行了

上测试~~

public class 排序 {
public static void main(String[] args) {
        List<SortA> listA = new ArrayList<>();
        SortA a1 = new SortA();
        a1.setName("a");
        a1.setAge(18);
        SortA a2 = new SortA();
        a2.setName("a");
        a2.setAge(19);
        SortA a3 = new SortA();
        a3.setName("b");
        a3.setAge(17);
        SortA a4 = new SortA();
        a4.setName("c");
        a4.setAge(17);
        SortA a5 = new SortA();
        a5.setName("d");
        a5.setAge(15);
        listA.add(a1);
        listA.add(a2);
        listA.add(a3);
        listA.add(a4);
        listA.add(a5);
        moreComparator(listA);
    }
public static void moreComparator(List<SortA> listA){
        //1.name正序,name一样age正序
        listA.sort(Comparator.comparing(SortA::getName).thenComparing(SortA::getAge));
        System.out.println(listA);
        //2.name倒序,name一样age正序
        listA.sort(Comparator.comparing(SortA::getName).reversed().thenComparing(SortA::getAge));
        System.out.println(listA);     			listA.sort(Comparator.comparing(SortA::getName,Comparator.reverseOrder()).thenComparing(SortA::getAge));
        System.out.println(listA);
        //3.name倒序,name一样age倒序
        listA.sort(Comparator.comparing(SortA::getName).thenComparing(SortA::getAge).reversed());
        System.out.println(listA);
  listA.sort(Comparator.comparing(SortA::getName,Comparator.reverseOrder()).thenComparing(SortA::getAge,Comparator.reverseOrder()));
        System.out.println(listA);
        //4.name正序,name一样age倒序
        listA.sort(Comparator.comparing(SortA::getName).reversed().thenComparing(SortA::getAge).reversed());
        System.out.println(listA);
	listA.sort(Comparator.comparing(SortA::getName).thenComparing(SortA::getAge,Comparator.reverseOrder()));
        System.out.println(listA);
    }
}

注意对象为空或者属性为空的情况

public class 排序 {
    public static void main(String[] args) {
        List<SortA> listA = new ArrayList<>();
        SortA a1 = new SortA();
        a1.setName("a");
        a1.setAge(18);
        SortA a2 = new SortA();
        a2.setName("a");
        a2.setAge(19);
        SortA a3 = new SortA();
        a3.setName("b");
        a3.setAge(17);
        SortA a4 = new SortA();
        a4.setName("c");
        a4.setAge(17);
        SortA a5 = new SortA();
       // a5.setName("d");
        a5.setAge(15);
        listA.add(a1);
        listA.add(a2);
        listA.add(a3);
        listA.add(a4);
        listA.add(a5);
        listA.add(null);
        nullComparator(listA);	
	}
    //如果对象或者属性为空
    public static void nullComparator(List<SortA> listA){
        //1.如果对象为空
      listA.sort(Comparator.nullsFirst(Comparator.comparing(SortA::getName,Comparator.nullsFirst(Comparator.naturalOrder()))));
        System.out.println(listA);
        //2.如果name为空
        //自然排序
        listA.sort(Comparator.comparing(SortA::getName,Comparator.nullsFirst(Comparator.naturalOrder())));
        listA.sort(Comparator.comparing(SortA::getName,Comparator.nullsFirst(String::compareTo)));
        System.out.println(listA);
        //反转
        listA.sort(Comparator.comparing(SortA::getName,Comparator.nullsFirst(Comparator.reverseOrder())));
        System.out.println(listA);
    }
}

总结

到此这篇关于Java排序之Comparable和Comparator比较器详解的文章就介绍到这了,更多相关Comparable和Comparator比较器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文