数据结构——Java对象的比较

news/2024/11/25 16:25:30/

目录

一、基本类型的比较

二、对象的比较

1、定义

2、方法

(1).覆写基类的equals

(2).基于Comparable接口类的比较

(3).基于比较器的比较

3、对比

三、集合框架中的PriorityQueue的比较方式

四、应用——解决Topk问题

1、PriorityQueue创建大根堆和小根堆

(1).使用比较器创建小根堆

(2).使用比较器创建大根堆

2、代码


 

一、基本类型的比较

Java中的基本类型的对象可以直接比较大小

public static void main(String[] args){int a=1;int b=2;System.out.println(a>b);    //falsedouble a1=1.1;double b1=1.2;System.out.println(a1<b1);    //truechar c='a';char d='b';System.out.println(c>d);    //flaseboolean e=false;boolean f=true;System.out.println(e==f);    //false
}

二、对象的比较

1、定义

Java中引用类型的变量不能直接按照“>”或“<”方式进行比较。但是可以用“==”进行比较,因为对于用户实现自定义类型,都是默认继承自Object类,Object类中提供了equal方法,而“==”默认情况下调用的就是equal方法。该方法的比较规则是没有比较引用变量引用对象的内容,而是直接比较引用变量的地址,因此很多时候不适用。

public boolean equals(Object obj){return (this==obj);//直接比较两个引用变量的地址
}

2、方法

(1).覆写基类的equals

public class dog{public int age;public String name;public dog(int age,String name){this.age=age;this.name=name;}@Overridepublic boolean equals(Object o){//与自身相比较,如果指向同一个对象,返回trueif(this==o){return true;}if(o==null||!(o instanceof dog)){//如果传入的为null,或者o不是dog的子类,返回falsereturn false;}dog d=(dog)o;//只要类中的两个对象都相等,就认为两个类相等return age==d.age&&name.equals(d.name);}	
}

注:覆写基类equal的方式虽然可以比较,但缺陷是equal只能按照相等进行比较,不能按照大于或小于的方式进行比较 。

(2).基于Comparable接口类的比较

Comparable是JDK提供的泛型的比较接口类。

public interface Comparable<E>{int compareTo(E o);//<0:表示this指向的对象小于o指向的对象//==0:表示this指向的对象等于o指向的对象//>0:表示this指向的对象大于o指向的对象
}

注:Comparable是java.lang中的接口类,可以直接使用,不需要导包

对于用户自定义类型,如果想要按照大小与方式进行比较时。在定义类时,实现Comparable接口即可,然后在类中重写compareTo方法。

public class dog implements Comparable<dog>{public int age;public String name;public dog(int age,String name){this.age=age;this.name=name;}@Overridepublic int compareTo(dog d){if(o==null){return 1;}return age-d.age;}public static void main(String[] args){dog d1=new dog(10,"二哈");dog d2=new dog(12,"二哈");dog d3=new dog(10,"二哈")System.out.println(d1.compareTo(d3));	//==0,表示相等System.out.println(d1.compareTo(d2));	//<0,表示d1比较小System.out.println(d2.compareTo(d1));	//>0,表示d2比较大}
}

(3).基于比较器的比较

用户自定义比较器类,实现Comparator接口

public interface Comparator<T>{int compare(T o1,T o2);//<0:表示o1指向的对象小于o2指向的对象//==0:表示o1指向的对象等于o2指向的对象//>0:表示o1指向的对象大于o2指向的对象
}

注:Comparator是java.util包中的泛型接口类,使用前需要导包

覆写Comparator中的compare方法

import java.util.Comparator;
class dog{public int age;public String name;public dog(int age,String name){this.age=age;this.name=name;}
}
class dogComparator implements Comparator<dog>{@Overridepublic int compare(dog d1,dog d2){if(d1==d2){return 0;}if(o1==null){return -1;}if(o2==null){return 1;}return d1.age-d2.age;}public static void main(String[] args){dog d1=new dog(10,"二哈");dog d2=new dog(12,"二哈");dog d3=new dog(10,"二哈");//定义比较器对象dogComparator c=new dogComparator();//使用比较器对象进行比较System.out.println(c.compare(d1,d3));	//==0,表示牌相等System.out.println(c.compare(d1,d2));	//<0,表示d1比较小System.out.println(c.compare(d2,d1));	//>0,表示d2比较大}
}

3、对比

Object.equals因为所有类都是继承自Object的,所以直接覆写即可,不过只能比较相等与否
Comparable.compareTo需要手动实现接口,侵入性较强,但一旦实现,每次用该类都有顺序,属于内部顺序
Comparator.compare需要实现一个比较器对象,对待比较类的侵入性弱,但对于算法代码实现侵入性强

三、集合框架中的PriorityQueue的比较方式

集合框架中的PriorityQueue底层使用堆结构,因此其内部的元素必须能够比大小,PriorityQueue采用了Comparable和Comparator两种方式

  • Comparable是默认的内部比较方式,如果用户插入自定义类型对象时,该类对象必须要实现Comparable接口,并覆写compareTo方法
  • 用户使用比较器对象时,如果用户插入自定义类型对象时,必须要提供一个比较器类,让该类实现Comparator接口并覆写compare方法

四、应用——解决Topk问题

1、PriorityQueue创建大根堆和小根堆

(1).使用比较器创建小根堆

class cmp1 implements Comparator<Integer>{@Overriderpublic int compare(Integer o1,Integer o2){return o1-o2;}
}

(2).使用比较器创建大根堆

class cmp2 implements Comparator<Integer>{@Overriderpublic int compare(Integer o1,Integer o2){return o2-o1;}
}

2、代码

public class test{public static int[] func(int[] array,int k){if(k<=0){return new int[k];}cmp2 c=new cmp2();PriorityQueue<Integer> maxHeap=new PriorityQueue<>(c);for(int i=0;i<k;i++){maxHeap.offer(array[i]);}for(int i=k;i<array.length;i++){int top=maxHeap.peek();if(array[i]<top){maxHeap.poll();maxHeap.offer(array[i]);}}int[] ret=new int[k];for(int i=0;i<k;i++){int val=maxHeap.poll();ret[i]=val;}return ret;}
}

 


http://www.ppmy.cn/news/22777.html

相关文章

AT155 高压绝缘电阻测试仪 都有哪些功能?

高压绝缘电阻测试仪是—款手持式仪表主要用来测量交流&#xff0f;直流电压、 电阻、 短路蜂鸣测试和 绝缘电阻测量。 式高压绝缘电阻测试仪具有4个量程用千绝缘电阻、 AC/DC电压、 电阻和短路蜂鸣测试。 设计达到以下安全标准 &#xff0e;绝缘测试量程O.lMn to 60Gn。 &a…

【AList】网盘聚合神器,打造灵活的私人云存储

一、AList简介 项目地址&#xff1a;https://github.com/alist-org/alist/blob/main/README_cn.md AList文档&#xff1a;https://alist.nn.ci/zh/guide/ AList是一个支持多种存储&#xff0c;支持网页浏览和 WebDAV 的文件列表程序。或者说是一个网盘聚合器。可以将你的网盘…

《小猫猫大课堂》三轮4——自定义类型(位段,枚举,联合)(内含通讯录)

宝子&#xff0c;你不点个赞吗&#xff1f;不评个论吗&#xff1f;不收个藏吗&#xff1f; 最后的最后&#xff0c;关注我&#xff0c;关注我&#xff0c;关注我&#xff0c;你会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的很重…

算法刷题打卡第82天:计算布尔二叉树的值

计算布尔二叉树的值 难度&#xff1a;简单 给你一棵 完整二叉树 的根&#xff0c;这棵树有以下特征&#xff1a; 叶子节点 要么值为 0 要么值为 1 &#xff0c;其中 0 表示 False &#xff0c;1 表示 True 。非叶子节点 要么值为 2 要么值为 3 &#xff0c;其中 2 表示逻辑或…

实现加盐加密

实现加盐加密存储密码1. MD52. 加盐加密实现&#xff1a;1&#xff09;修改 password 为 64 位字符串2&#xff09;创建 SecurityUtil 类 (加盐加密类)应用存储密码 1. MD5 Spring 提供了库 import org.springframework.util.DigestUtils; &#xff0c;我们可以进行 MD5 加密&…

react源码中的生命周期和事件系统

这一章我想跟大家探讨的是React的生命周期与事件系统。 jsx的编译结果 因为前面也讲到jsx在v17中的编译结果&#xff0c;除了标签名&#xff0c;其他的挂在标签上的属性&#xff08;比如class&#xff09;&#xff0c;事件&#xff08;比如click事件&#xff09;&#xff0c;都…

Attention-自注意机制

Attention-自注意机制 Attention 可以大幅提升seq2seq的遗忘问题。有了Attention&#xff0c;Seq2Seq 模型不会忘记源输入&#xff0c;且decoder解码器就知道该把注意力集中在哪里。 缺点: 计算量大得多 Original paper: • Bahdanau,Cho,& Bengio. Neural machine trans…

React中的jsx语法转换后生成虚拟DOM,再挂载到真实的DOM中的全过程讲解

前言 react中的jsx语法很多伙伴都会使用&#xff0c; 但是你知道它的本质是什么吗&#xff1f;运行中它会做如何的转换呢&#xff1f;jsx内部又是怎么生成了虚拟DOM&#xff1f;虚拟DOM又是如何挂载到真实DOM上去的呢&#xff1f; 带着这些问题&#xff0c;我们做个讲解把&…