参考:https://www.cnblogs.com/igoodful/p/9517784.html


Collections有两种比较规则方式,第一种是使用自身的比较规则:

该类必须实现Comparable接口并重写comparTo方法。

this可以想象为1,传入对象o想象为2,返回1-2即按升序排序。返回2-1即按降序排序。

1、首先编写一个实现Comparable接口的实体类

  1. package com.abc;
  2. //Comparable接口后面一定要加上需要比较的数据类型
  3. public class Person implements Comparable<Person>{
  4.  
  5. private String name;
  6. private int age;
  7. private int salary;
  8.  
  9. public Person() {
  10. }
  11.  
  12. public Person(String name, int age, int salary) {
  13. this.name = name;
  14. this.age = age;
  15. this.salary = salary;
  16. }
  17.  
  18. public String getName() {
  19. return name;
  20. }
  21.  
  22. public void setName(String name) {
  23. this.name = name;
  24. }
  25.  
  26. public int getAge() {
  27. return age;
  28. }
  29.  
  30. public void setAge(int age) {
  31. this.age = age;
  32. }
  33.  
  34. public int getSalary() {
  35. return salary;
  36. }
  37.  
  38. public void setSalary(int salary) {
  39. this.salary = salary;
  40. }
  41.  
  42. @Override
  43. public String toString() {
  44. return "Person{" +
  45. "name='" + name + '\'' +
  46. ", age=" + age +
  47. ", salary=" + salary +
  48. '}';
  49. }
  50.  
  51. //自身定义年龄升序
  52. @Override
  53. public int compareTo(Person o) {
  54. return this.age-o.age;
  55. }
  56. }

2、编写测试代码

  1. package com.abc;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.List;
  6.  
  7. public class PersonTest {
  8.  
  9. public static void main(String[] args){
  10. List<Person> people = new ArrayList<>();
  11. people.add(new Person("AAA",20,100));
  12. people.add(new Person("BBB",18,109));
  13. people.add(new Person("CCC",30,58));
  14.  
  15. System.out.println(people);
  16. Collections.sort(people);
  17. System.out.println(people);
  18. }
  19. }

3、运行结果

  1. [Person{name='AAA', age=20, salary=100}, Person{name='BBB', age=18, salary=109}, Person{name='CCC', age=30, salary=58}]
    //完成了年龄的升序排列
  2. [Person{name='BBB', age=18, salary=109}, Person{name='AAA', age=20, salary=100}, Person{name='CCC', age=30, salary=58}]

第二个参数为比较器,可以使用它来定义针对集合排序时的比较元素大小的规则。

使用这种方式时,sort方法不要求集合元素必须实现Comparable接口了,因为不会使用元素自身的比较规则

1、编写一个普通的实体类,不需要实现任何接口

  1. package com.abcd;
  2.  
  3. public class Person{
  4.  
  5. private String name;
  6. private int age;
  7. private int salary;
  8.  
  9. public Person() {
  10. }
  11.  
  12. public Person(String name, int age, int salary) {
  13. this.name = name;
  14. this.age = age;
  15. this.salary = salary;
  16. }
  17.  
  18. public String getName() {
  19. return name;
  20. }
  21.  
  22. public void setName(String name) {
  23. this.name = name;
  24. }
  25.  
  26. public int getAge() {
  27. return age;
  28. }
  29.  
  30. public void setAge(int age) {
  31. this.age = age;
  32. }
  33.  
  34. public int getSalary() {
  35. return salary;
  36. }
  37.  
  38. public void setSalary(int salary) {
  39. this.salary = salary;
  40. }
  41.  
  42. @Override
  43. public String toString() {
  44. return "Person{" +
  45. "name='" + name + '\'' +
  46. ", age=" + age +
  47. ", salary=" + salary +
  48. '}';
  49. }
  50.  
  51. }

2、编写测试代码

  1. package com.abcd;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.Comparator;
  6. import java.util.List;
  7.  
  8. public class PersonTest {
  9. public static void main(String[] args){
  10. List<Person> people = new ArrayList<>();
  11. people.add(new Person("AAA",20,100));
  12. people.add(new Person("BBB",18,109));
  13. people.add(new Person("CCC",30,58));
  14.  
  15. System.out.println(people);
         //排序规则 salary降序
  16. Collections.sort(people, new Comparator<Person>() {
  17. @Override
  18. public int compare(Person o1, Person o2) {
  19. return o2.getSalary()- o1.getSalary();
  20. }
  21. });
  22. System.out.println(people);
  23. }
  24. }

3、运行结果

  1. [Person{name='AAA', age=20, salary=100}, Person{name='BBB', age=18, salary=109}, Person{name='CCC', age=30, salary=58}]
  2. [Person{name='BBB', age=18, salary=109}, Person{name='AAA', age=20, salary=100}, Person{name='CCC', age=30, salary=58}]

  

总结

总结一下,两种比较器Comparable和Comparator,后者相比前者有如下优点:

1、如果实现类没有实现Comparable接口,又想对两个类进行比较(或者实现类实现了Comparable接口,但是对compareTo方法内的比较算法不满意),那么可以实现Comparator接口,自定义一个比较器,写比较算法

2、实现Comparable接口的方式比实现Comparator接口的耦合性 要强一些,如果要修改比较算法,要修改Comparable接口的实现类,而实现Comparator的类是在外部进行比较的,不需要对实现类有任何修 改。从这个角度说,其实有些不太好,尤其在我们将实现类的.class文件打成一个.jar文件提供给开发者使用的时候。实际上实现Comparator 接口的方式后面会写到就是一种典型的策略模式

当然,这不是鼓励用Comparator,意思是开发者还是要在具体场景下选择最合适的那种比较器而已。

十三、实现Comparable接口和new Comparator<T>(){ }排序的实现过程的更多相关文章

  1. java通过Comparable接口实现字符串比较大小排序的简单实例

    /** * 对象比较大小compare的用法 字符串排序 * 练习代码, 给定字符串" nba" "cba" "ncaa" "wb ...

  2. Comparable接口——容器中自定义类排序

    1.容器TreeMap,默认根据Key对象中某个属性的从小到大排列元素. (1)如下代码示例,Key是整型数字,所以按照其从小到大的顺序排列 public class TestTreeMap { pu ...

  3. 关于comparator接口和comparable接口以及它们各自的方法compare()和compareTo()

    在今天做的LeetCode的题中有两道都出现了利用接口实现对象的排序.两题的相关链接: 1.利用comparable接口对对象排序 2.利用comparator接口实现排序 因为之前都没接触过这两个接 ...

  4. Java中Comparator接口和Comparable接口的使用

    普通情况下在实现对对象元素的数组或集合进行排序的时候会用到Comparator和Comparable接口,通过在元素所在的类中实现这两个接口中的一个.然后对数组或集合调用Arrays.sort或者Co ...

  5. 12.Java中Comparable接口,Readable接口和Iterable接口

    1.Comparable接口 说明:可比较(可排序的) 例子:按照MyClass的y属性进行生序排序 class MyClass implements Comparable<MyClass> ...

  6. java.lang.Comparable接口

    转自:http://blog.csdn.net/zccst/article/details/5092920 java.lang.Comparable 接口 作者: zccst java.lang.Co ...

  7. 考虑实现Comparable接口

    考虑实现Comparable接口   compareTo方法没有在Object中声明.相反,它是Comparable接口中唯一的方法.compareTo方法不但允许进行简单的等同性比较,而且允许执行顺 ...

  8. Comparable接口的使用

    功能: Comparable接口可用于对象的排序或者对象的分组 介绍: Comparable接口强行对实现它的类的每个实例进行自然排序,该接口的唯一方法compareTo方法被称为自然比较方法 方法: ...

  9. comparator接口与Comparable接口的区别

    1. Comparator 和 Comparable 相同的地方 他们都是java的一个接口, 并且是用来对自定义的class比较大小的, 什么是自定义class: 如 public class Pe ...

随机推荐

  1. C语言排序算法学习笔记——交换类排序

    交换类排序:根据序列中两个元素关键字的比较结果来交换他俩在序列中的位置. 冒泡排序:假设待排序表长为n,从后往前(或从前往后)两两比较相邻元素的值,若为逆序(即A[i-1]>A[i])则交换他们 ...

  2. (转)SQLServer_十步优化SQL Server中的数据访问 三

    原文地址:http://tech.it168.com/a2009/1125/814/000000814758_all.shtml 第六步:应用高级索引 实施计算列并在这些列上创建索引 你可能曾经写过从 ...

  3. shell中使用类似Python的参数处理

    params=$* for param in ${params} do name=$() value=$() if [[ "$name" = "run_type" ...

  4. sql优化使用技巧

    1.LIMIT 语句分页查询是最常用的场景之一,但也通常也是最容易出问题的地方.比如对于下面简单的语句,一般 DBA 想到的办法是在 type, name, create_time 字段上加组合索引. ...

  5. 关于全局变量,static,define和const

        其实按照现在主流的观点,应该尽量少用全局变量和define,尽量多用临时变量,并且用const替换值define,用短小精悍的函数替换函数define.     对这些我倒是也没有什么意见,只 ...

  6. JSTL的使用

    使用JSTL前的准备 想要使用JSTL,首先需要给工程导入JSTL的包(JSTL.jar和standard.jar). JSTL标签库 在JSTL中分为以下五个标签 核心标签 格式化标签 SQL标签 ...

  7. C 语言能不能在头文件定义全局变量?

    可以,但一般不会将全局变量的定义写在头文件中. 因为如果多个 C 源文件都添加了头文件,很容易引起重定义的问题.这时候一般编译器都会提示:“multiple definition of... firs ...

  8. Django04-模板系统Template

    一.模板支持的语法 Django模板中只需要记两种特殊符号: {{ }}表示变量,在模板渲染的时候替换成值{% %}表示逻辑相关的操作. 二. 变量(使用双大括号来引用变量) 1.语法格式:{{var ...

  9. 用原生js简单模仿angular的依赖注入

    大家都知道angular 依赖注入很神奇,跟我们平常写代码的风格思维差别很大,不过仔细分析确是一个很有意思的东西,依赖注入早期也叫依赖倒置,是java中有的.废话不多少直接上例子 本帖属于原创,转载请 ...

  10. 将ipad作为电脑拓展屏或分屏的简单方法

    用Ipad实现电脑分屏的方法是挺简单的,但鉴于部分小白找不到合适的门路,在此重新分享一下. 需要的装备:  ipad   电脑   数据连接线 方法:某宝上搜索 duet display ,只需1元左 ...