Java排序之Comparator和Comparable比较

2024-06-22 16:58

本文主要是介绍Java排序之Comparator和Comparable比较,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1 引言
    • 1.1 Comparable排序
    • 1.2 Comparator大小
    • 1.3 两者区别

1 引言

ComparatorComparable名字比较相似,但是作用不同,Comparator接口比较大小,Comparable接口进行排序,但是具体怎么用还得慢慢来看

1.1 Comparable排序

Comparable是排序接口。若一个类实现了Comparable接口,就意味着该类支持排序。实现了Comparable接口的类的对象的列表数组可以通过Collections.sortArrays.sort进行自动排序
接口定义如下:

package java.lang;
import java.util.*;
public interface Comparable<T> 
{public int compareTo(T o);
}

T表示可以与此对象进行比较的那些对象的类型。
此接口只有一个方法compare,比较此对象与指定对象的顺序,如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
现在我们假设一个Person类,代码如下:

public class Person
{String name;int age;public Person(String name, int age){super();this.name = name;this.age = age;}public String getName(){return name;}public int getAge(){return age;}
}

现在有两个Person类的对象,我们如何来比较二者的大小呢?我们可以通过让Person实现Comparable接口

public class Person implements Comparable<Person>
{String name;int age;public Person(String name, int age){super();this.name = name;this.age = age;}public String getName(){return name;}public int getAge(){return age;}@Overridepublic int compareTo(Person p){return this.age-p.getAge();}public static void main(String[] args){Person[] people=new Person[]{new Person("test", 20),new Person("demo", 10)};System.out.println("排序前");for (Person person : people){System.out.print(person.getName()+":"+person.getAge());}Arrays.sort(people);System.out.println("\n排序后");for (Person person : people){System.out.print(person.getName()+":"+person.getAge());}}
}

1.2 Comparator大小

Comparator是比较接口,我们如果需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口),那么我们就可以建立一个该类的比较器来进行排序,这个比较器只需要实现Comparator接口即可。也就是说,我们可以通过实现Comparator来新建一个比较器,然后通过这个比较器对类进行排序。该接口定义如下:

package java.util;
public interface Comparator<T>{int compare(T o1, T o2);boolean equals(Object obj);}

注意:

  1. 若一个类要实现Comparator接口:它一定要实现compare(T o1, T o2) 函数,但可以不实现 equals(Object obj) 函数。
  2. int compare(T o1, T o2)比较o1和o2的大小。返回负数,意味着o1比o2小;返回,意味着o1等于o2;返回正数,意味着o1大于o2

假如上面的Person类没有实现Comparable接口,该如何比较大小呢?我们可以新建一个类,让其实现Comparator接口,从而构造一个“比较器"。

public class PersonCompartor implements Comparator<Person>
{@Overridepublic int compare(Person o1, Person o2){return o1.getAge()-o2.getAge();}
}
现在我们就可以利用这个比较器来对其进行排序:public class Person
{String name;int age;public Person(String name, int age){super();this.name = name;this.age = age;}public String getName(){return name;}public int getAge(){return age;}public static void main(String[] args){Person[] people=new Person[]{new Person("test", 20),new Person("demo", 10)};System.out.println("排序前");for (Person person : people){System.out.print(person.getName()+":"+person.getAge());}Arrays.sort(people,new PersonCompartor());System.out.println("\n排序后");for (Person person : people){System.out.print(person.getName()+":"+person.getAge());}}
}

转载于:https://www.cnblogs.com/szlbm/p/5504634.html

1.3 两者区别

这两个接口的比较:

  • Comparable相当于内部比较器,而Comparator相当于外部比较器Comparable是在集合内部定义的方法实现的排序,Comparator是在集合外部实现的排序

  • Comparable是排序接口,若一个类实现了Comparable接口,就意味着该类支持排序,可以使用Collections.sortArrays.sort进行自动排序。而Comparator是比较器,若需要控制某个类的次序,可以建立一个该类的比较器来进行排序。

  • 两种方法各有优劣, 用Comparable 简单, 只要实现Comparable接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了

  • Comparator可以看成一种算法的实现,将算法和数据分离,Comparator也可以在下面两种环境下使用:
    类的设计师没有考虑到比较问题而没有实现Comparable,可以通过Comparator来实现排序而不必改变对象本身;可以使用多种排序标准,比如升序、降序等。

这篇关于Java排序之Comparator和Comparable比较的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1084873

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

Java中的.close()举例详解

《Java中的.close()举例详解》.close()方法只适用于通过window.open()打开的弹出窗口,对于浏览器的主窗口,如果没有得到用户允许是不能关闭的,:本文主要介绍Java中的.... 目录当你遇到以下三种情况时,一定要记得使用 .close():用法作用举例如何判断代码中的 input

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S