Comparable 和 Comparator

深度剖析—Comparable和Comparator 1. 需要被排序的对象实现Comparable 接口,所以可以认为比较的属性是对象本身已经有了的,所以我们将由Comparable 实现的排序叫做自然排序 2. 当Comparable 实现的排序不能满足需求的时候,你可以使用Comparator 进行排序,这个往往是因为需要排序的对象的类的定义已经存在的时候(或者说是这个类不是你定义的) 3. 有时候我们可以使用Comparator 提供的两个方法来改变Comparable的排序类型,或者说是排序方向 阅读详情
Comparable与Comparator

**Comparable 和 Comparator** 都是用来实现集合中元素的比较、排序的。

只是 Comparable 是在集合内部定义的方法实现的排序,而Comparator 是在集合外部实现的排序,

所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。

Comparator位于包java.util下,而Comparable位于包 java.lang下

一.Comparable 是一个对象,本身就已经支持自比较所需要实现的接口(如 String、Integer 自己就可以完成比较大小操作,已经实现了Comparable接口)

自定义的类要在加入list容器中后能够排序,可以实现Comparable接口,在用Collections类的sort方法排序时,如果不指定Comparator,那么就以自然顺序排序,这里的自然顺序就是实现Comparable接口设定的排序方式。

二.Comparator 是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。
可以说一个是自已完成比较,一个是外部程序实现比较的差别而已。

用 Comparator 是策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。

1.Comparable用法示例:

需求:

每一个学生都有对应的归属地。
学生Student,地址String
学生属性:姓名,年龄
注意:姓名和年龄相同的视为同一个学生,保证学生的唯一性。

1.描述学生。
2.定义map容器,将学生作为键,地址作为值。存入。
3.获取map集合中的元素。

A.(代码MapTest.java)

package com.zlc.collection;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

class Student6 implements Comparable<Student6>{
 private String name;
 private int age;
 public Student6(String name, int age) {
  super();
  this.name = name;
  this.age = 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 String toString(){
  return "姓名:"+name+"-->年龄:"+age;
 }
 //复写hashCode()和equals()方法
 public int hashCode() {
  return name.hashCode()+age*34;
 }
 public boolean equals(Object obj) {
  if(!(obj instanceof Student6)) {
   throw new ClassCastException("类型不匹配-->不是学生对象");
  }

  Student6 s = (Student6) obj;
  return this.name.equals(s.name) && this.age == s.age;
 }
 @Override
 public int compareTo(Student6 o) {
  int num = new Integer(this.age).compareTo(new Integer(o.age));

  if(num == 0){
   return this.name.compareTo(o.name);
  }
  return num;
 }
}

public class MapTest {

 public static void main(String[] args) {
  HashMap<Student6,String> hm = new HashMap<Student6,String>();//注:HashMap是无序存放的。

  hm.put(new Student6("xiaozhou",21), "商丘");
  hm.put(new Student6("xiaozhou",21), "南阳");//此键值与上面的相同,会将上面的value覆盖
  hm.put(new Student6("xiaowang",22), "新乡");
  hm.put(new Student6("xiaochen",20), "郑州");
  hm.put(new Student6("xiaoliu",19), "开封");

  //第一种取出方式 keySet
  Set<Student6> keySet = hm.keySet();//取出键集

  Iterator<Student6> it = keySet.iterator();

  while(it.hasNext()){
   Student6 stu = it.next();//取得学生对象stu
   String addr = hm.get(stu);//注:取出stu对应的地址addr,地址在HashMap里面,用hm取出
   System.out.println(stu+" ...居住地址:"+addr);//这里的stu就会自动调用 Student6中的toString()方法
  }

  System.out.println("---------------------------");
  //第二种取出方式 entrySet
  Set<Map.Entry<Student6, String>> entrySet = hm.entrySet();

  Iterator<Map.Entry<Student6, String>> iter = entrySet.iterator();

  while(iter.hasNext()){
   Map.Entry<Student6, String> me = iter.next();
   Student6 stu = me.getKey();
   String addr = me.getValue();

   System.out.println(stu+" ...居住地址:"+addr);//这里的stu就会自动调用 Student6中的toString()方法
  }
  }

}

2.Comparator用法(其中也用到了Comparable,顺便比较一下。)
需求一:(在不使用Comparator的情况下)
对学生对象的年龄进行升序排序。
因为数据是以键值对形式存在的。
所以要使用可以排序的Map集合。TreeMap
需求二:(在使用Comparator的情况下)
先对学生对象的姓名进行升序排序,再按年龄升序。
B.(代码MapTest2.java)
package com.zlc.collection;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

class Student7 implements Comparable<Student7> {//除了要重写Object对象的方法之外,还要实现Comparable接口的比较方法
 private String name;
 private int age;
 public Student7(String name, int age) {
  super();
  this.name = name;
  this.age = 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;
 }

 @Override
 public boolean equals(Object obj) {
  if(!(obj instanceof Object)){
//   return false;
   throw new ClassCastException("类型不匹配,不是学生对象");
  }
  Student7 stu = (Student7) obj;
  return this.name.equals(stu.name) && this.age == stu.age;
 }
 @Override
 public int hashCode() {
//  return super.hashCode();
  return name.hashCode()+age*17;
 }
 @Override
 public String toString() {
  return "name: "+name+"-->age: "+age;
 }
 @Override//重写比较方法
 public int compareTo(Student7 s) {
  int num = new Integer(this.age).compareTo(new Integer(s.age));//按年龄从小到大进行排序

  if(num == 0){//如果年龄相同,再比较姓名,(姓名按Unicode编码升序排序)
   return this.name.compareTo(s.name);
  }
  return num;
 }


}

class StuNameComparator implements Comparator<Student7>{//在同时使用Comparable和Comparator的情况下,如果实现了比较器接口进行比较

 @Override
 public int compare(Student7 s1, Student7 s2) {
  int num = s1.getName().compareTo(s2.getName());//按姓名排序

  if(num == 0){//如果名字相同,再比较年龄(如果年龄又相同,则不能加入到TreeMap集合中去)
   return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
  }
  return num;
 }

}

public class MapTest2 {

 public static void main(String[] args) {
  /*
   * TreeMap(Comparator<? super K> comparator) 
           构造一个新的、空的树映射,该映射根据给定比较器进行排序。
   * */
  TreeMap<Student7,String> tm = new TreeMap<Student7,String>(new StuNameComparator());

  tm.put(new Student7("zhangsan",21), "北京");
  tm.put(new Student7("lisi",19), "上海");
  tm.put(new Student7("wangwu",24), "深圳");
  tm.put(new Student7("wangwu",18), "开封");
  tm.put(new Student7("xiaohuan",22), "商丘");
  tm.put(new Student7("xiaocheng",22), "新乡");
  tm.put(new Student7("xiaocheng",22), "郑州");//如果该映射以前包含此键的映射关系,那么将替换旧值。
  tm.put(new Student7("xiaohuan",22), "商丘");

  Set<Map.Entry<Student7,String>> entrySet = tm.entrySet();

  Iterator<Map.Entry<Student7, String>> it = entrySet.iterator();

  while(it.hasNext()){
   Map.Entry<Student7, String> me = it.next();

   Student7 st = me.getKey();
   String addr = tm.get(st);//通过对应的st获得对应的地址

   System.out.println(st+" ...居住地址:"+addr);
  }
 }

}



说明:
在排序时,如果不是调用sort方法,相要直接比较两个对象的大小,如下:

Comparator定义了俩个方法,分别是 int compare(T o1, T o2)和 boolean equals(Object obj),

用于比较两个Comparator是否相等

true only if the specified object is also a comparator and it imposes the same ordering as this comparator.

有时在实现Comparator接口时,并没有实现equals方法,可程序并没有报错,原因是实现该接口的类也是Object类的子类,而Object类已经实现了equals方法
Comparable接口只提供了 int compareTo(T o)方法,也就是说假如我定义了一个Person类,这个类实现了 Comparable接口,那么当我实例化Person类的person1后,我想比较person1和一个现有的Person对象person2的大小时,我就可以这样来调用:person1.comparTo(person2),通过返回值就可以判断了;而此时如果你定义了一个 PersonComparator(实现了Comparator接口)的话,那你就可以这样:PersonComparator comparator= new PersonComparator();
comparator.compare(person1,person2);。
【教程4>第10章>第13节】基于FPGA的图像双边滤波开发——单通道双边滤波Verilog实现 本文介绍了基于Vivado 2022.2的单通道高斯滤波FPGA实现方案。主要内容包括:1)采用3×3窗口像素提取、高斯权值计算、exp指数运算等模块构建双边滤波系统;2)详细分析了Verilog HDL实现的顶层设计文件,包含窗口数据生成、指数计算、混合权重、归一化处理等关键模块;3)展示了图像双边滤波器的RTL结构图。该设计为后续实现RGB三通道图像高斯滤波及MATLAB联合仿真奠定了基础。 阅读详情

相关推荐

新手也能搞定!用ADS 2023从零设计一个超宽带Wilkinson功分器(附完整版图)

本文详细介绍了如何使用ADS 2023从零开始设计超宽带Wilkinson功分器,涵盖介质板参数设置、微带线计算优化、版图生成验证等关键步骤。通过实例演示和常见问题排查,帮助射频工程新手快速掌握功分器设计技巧,提升设计效率。

weixin_42692935的博客 476

java 定制排序 Comparator 区分从大到小还是从小到大

比如定义一个类,在类中重新定义Collection.sort()排序规则: class ComparatorDp implements Comparator{ public int compare(Object obj1, Object obj2) { double temp=obj1.value()-obj2.value(); ...

私房菜 7276

【Python程序开发】湖南省职业院校技能大赛python程序开发赛项样题二

【Python程序开发】湖南省职业院校技能大赛python程序开发赛项样题二

况老师话竞赛&blog 2197

comparable与comparator的区别

Comparable 和 Comparator 都是用来实现集合中元素的比较、排序的。 只是 Comparable 是在集合内部定义的方法实现的排序,而Comparator 是在集合外部实现的排序, 所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。 Comparator位于包java.util下,而Comp

小飞鱼的blablabla... 793

如何使用Ray和PyTorch训练模型

用户编写训练函数 → 定义单机训练逻辑。通过扩缩容配置 → 指定需要多少资源(Worker 数量、CPU/GPU)。训练器整合训练函数和配置 → 自动将训练函数分发到多个 Worker 上并行执行。Worker 运行训练函数 → 在分布式环境中完成模型训练。通过这种模式,Ray Train 实现了对分布式训练的抽象,用户只需关注单机训练逻辑,无需手动管理分布式通信和资源分配。

m0_62464865的博客 1922

AutoGenTestCase - AI大模型生成测试用例

AI技术助力高效软件测试:AutoGenTestCase工具介绍 传统手工测试存在效率低、覆盖不全等痛点。AutoGenTestCase工具集成DeepSeek、通义千问等AI大模型,能快速解析需求并自动生成标准化测试用例,将数小时工作缩短至分钟级。该工具部署简单,仅需配置APIKey即可运行,支持多种测试用例类型比例设置,并输出Markdown和Excel格式的测试用例。通过GitHub或网盘下载后,用户可按照教程完成APIKey配置、需求文档上传和用例生成等操作,显著提升测试效率与覆盖完整性。

YIqifeibaQI的博客 348

java 排序 comparable_java中的排序1:comparable和comparator(转)

分三种情况:简单类型排序。内部对象实现comparable。外部对象实现comparator。1、简单类型的排序简单类型不外是byte, char, short, int, long, float, double等数据类型,这些类型不能放在聚集中,只能使用数组。java.util.Arrays方法提供了对这些类型的sort方法(实际上还有很多其他有用的方法),下面是对一个简单的int数组排序:in...

weixin_39814378的博客 210

Power BI应用案例:淘宝用户行为分析实战

一、案例背景 基于千万级的淘宝用户的使用记录,对淘宝用户的行为进行分析,具体指标包括:日PV、日UV、小时PV、小时UV、不同用户行为的PV、用户购买次数分布、用户购买频次分布、活跃用户消费情况等。通过本案例,可以基本看看Power BI都能分析达到怎么样的效果。 二、数据来源及结构 阿里天池官方发布的1万用户在2014年双十二期间的行为记录,数据量达1200万+。 数据下载地址:...

灰哥数据智能的专栏 1万+

Comparable 的用法~血泪史~

最近效率比较低~可能是因为没有电话骚扰TM吧~哎~ 没法~ 她要考试! 想实践一个 java.lang.Comparable 接口,看了半天的API文档~ 好像看懂了~ 但是不会用。。 只知道会  需要return +1 -1 0 然后就糊里糊涂就开始写了~ class TestInter implements Comparable { int x = 1; pub

swufer 6455

Spatial-ORMLLM: Improve Spatial Relation Understanding in the Operating Room with Multimodal Larg...

手术室(OR)中的精准空间建模是众多临床任务的基础,可为术中感知、风险规避及手术决策提供支持。现有方法虽利用大规模多模态数据集进行 latent 空间对齐,以隐式学习空间关系,但却忽视了多模态大型语言模型(MLLM)的3D能力。然而,这种方法存在两个问题:1)手术室通常缺乏多台视频和音频传感器,多模态3D数据难以获取;2)仅依赖易获取的2D数据训练,无法捕捉复杂场景中的细粒度细节。为解决这一问题,我们提出——首个针对手术室3D空间推理的大型视觉语言模型。

UnknownBody_2的博客 592

Unity-Mirror网络框架-从入门到精通之Mirror简介

在现代游戏开发中,网络功能日益成为提升游戏体验的关键组成部分。Mirror是一个用于Unity的开源网络框架,专为多人游戏开发设计。它使得开发者能够轻松实现网络连接、数据同步和游戏状态管理。本文将深入介绍Mirror的基本概念、如何与其他网络框架进行比较,以及如何从零开始创建一个使用Mirror的简单网络项目。Mirror是一个功能强大的Lite网络框架,旨在替代Unity的UNet网络解决方案。它提供了高效的多玩家架构、简单易用的API,以及良好的社区支持。

TxNet 3089

Comparator和Comparable的区别

文章目录 一、概述 二、Comparable 三、Comparator 四、Comparator和Comparable的区别 五、实现方式 一、概述   Comparable和Comparator都是两个接口,接口都可以用来实现集合中元素的比较、排序,Comparator位于包java.util下,而Comparable位于包java.lang下,Comparable接口将比较代码嵌入自身类中,而Comparator既可以嵌入到自身类中,也可以在一个独立的

m0_71087031的博客 1万+

Ghost卷积原理与构建YOLOv11的GhostNet变体

本文探讨了在边缘设备部署YOLOv11时使用Ghost卷积进行模型轻量化的实践经验。针对Jetson Nano的4GB内存限制,作者通过替换Backbone中的3x3标准卷积为Ghost卷积,实现了参数减少28%、推理速度提升38%,仅损失1.1%mAP的优化效果。文章详细介绍了Ghost卷积的实现原理、在YOLOv11中的具体替换策略,以及训练调参和部署优化的关键技巧。作者强调轻量化是计算效率与模型性能的权衡,建议工程团队保留原模型和Ghost变体两个版本,根据实际需求灵活切换。Ghost卷积的核心价值在

as1225120794的博客 169

浅析 Comparable和 Comparator的区别

简介 Comparable和 Comparator都是java.util包下的两个接口,从字面上看这两个接口都是用来做比较用的,但是jdk里面不可能定义两个功能相同的接口,所以他们肯定有不同的用处。 1、Comparable 1.1 说明 Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些 类是可以和自己比较的,至于具体和另一个实现了Compar...

wlh2015的博客 3万+

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Comparable 和 Comparator 接口的区别

在Java中,Comparable 和 Comparator 两个接口经常用于对象排序。然而,它们在使用场景和实现细节上存在显著的区别。本文将详细介绍这两个接口的主要区别以及它们各自的作用。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 7011

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

comparable 和 comparator

comparable 和 comparator

我从不打没有准备的仗! 9329

详解Comparable和Comparator

如果是想要以score为基准Comparable接口的功能就是用于对象之间的比较。那个也就是说比较的主要实现逻辑就在compareTo方法中。,从大到小排序,只需要把compareTo中的this和o调换位置即可。

qq_63525426的博客 1644

Comparator和Comparable

都是Java中用于对象排序的接口,它们各有优劣,适用于不同的场景。理解它们的区别和使用方法,对于编写清晰、高效的排序代码至关重要。在实际开发中,应根据具体需求选择合适的接口,实现所需的排序逻辑。都是用于排序的接口。它们提供了自定义对象排序的机制,但实现方式和使用场景有所不同。的区别与联系有所帮助。希望以上内容对您理解。

liu_rockefeller的博客 930

Comparable和Comparator的区别

简述Comparable和Comparator的区别

weixin_55758279的博客 1103

Java中Comparable与Comparator

Java中Comparable与Comparator的区别

m0_46596099的博客 2031

java Comparable和Comparator分析

Comparable和Comparator分析

水w的博客 1095

Comparable和Comparator

Java比较器Comparable和Comparator详解 排序原理简介 数组Arrays.sort()排序原理 通过Java API文档知道,Arrays.sort()调用的是DualPivotQuicksort.sort()方法,如下代码片段所示: public static void sort(int[] a) { DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); } DualPivotQuicksort.s

Gandoph的博客 1171

Comparator 和 Comparable

Comparator 和 Comparable 相同点 Comparator 和 Comparable都是java的接口,并且是用来对自定义的class比较大小的。 对于自定义类如:public class Person{ String name; int age }.   当我们有这么一个personList,里面包含了person1, person2, persion3……,我们用Collections.sort( personList )是得不到预期的结果的。这时肯定有人要问,那为什么可以排序一个字符

Frank---7的博客 3229
上一篇: Comparable与Comparator
下一篇: java--SAX解析xml
剑之所向
博客等级 码龄11年 228粉丝 110原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值