【javaSE】中基本类型和引用类型对象的比较及PriorityQueue中的比较方法

news2024/12/29 14:21:05

写博客是为了提升自己,也是为了展现自己的学习成果,坚持!坚持!坚持!未来是什么样的,闯一闯就知道啦。喜欢就留个关注吧!!!

目录

一、java对象的比较

1.1java中基本类型的比较

1.2引用对象的比较

1.3引用对象基于Comparble接口类的比较

 1.4引用对象基于比较器的比较

1.5三种方式的对比

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

2.1PriorityQueue中的比较方式


一、java对象的比较

1.1java中基本类型的比较

在Java中,基本类型的对象可以直接比较大小。例如:int,char,boolean,float,double...

public class Test {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println(a > b);
        System.out.println(a < b);
        System.out.println(a == b);
        char c1 = 'A';
        char c2 = 'B';
        System.out.println(c1 > c2);
        System.out.println(c1 < c2);
        System.out.println(c1 == c2);
        boolean b1 = true;
        boolean b2 = false;
        System.out.println(b1 == b2);
        System.out.println(b1 != b2);
    }
}

1.2引用对象的比较

对引用对象进行比较,需要重写某些接口的方法,下面我来演示一下

class Card {
public int rank; // 数值
public String suit; // 花色
public Card(int rank, String suit) {
this.rank = rank;
this.suit = suit;
}
}
public class TestPriorityQueue {
public static void main(String[] args) {
Card c1 = new Card(1, "♠");
Card c2 = new Card(2, "♠");
Card c3 = c1;
//System.out.println(c1 > c2); // 编译报错
System.out.println(c1 == c2); // 编译成功 ----> 打印false,因为c1和c2指向的是不同对象
//System.out.println(c1 < c2); // 编译报错
System.out.println(c1 == c3); // 编译成功 ----> 打印true,因为c1和c3指向的是同一个对象
}
}

 c1、c2和c3分别是Card类型的引用变量,上述代码在比较编译时:
c1 > c2 编译失败
c1== c2 编译成功
c1 < c2 编译失败

从编译结果可以看出,Java中引用类型的变量不能直接按照 > 或者 < 方式进行比较。 那为什么==可以比较?

因为:对于用户实现自定义类型,都默认继承自Object类,而Object类中提供了equal方法,而==默认情况下调用的就是equal方法,但是该方法的比较规则是:没有比较引用变量引用对象的内容,而是直接比较引用变量的地址,但有些情况下该种比较就不符合题意。

equals源码:

// Object中equal的实现,可以看到:直接比较的是两个引用变量的地址
public boolean equals(Object obj) {
return (this == obj);
}

那么我们想要去比较对象,可以去重写Object类的equals方法

@Override
public boolean equals(Object o) {
// 自己和自己比较
if (this == o) {
return true;
}
// o如果是null对象,或者o不是Card的子类
if (o == null || !(o instanceof Card)) {
return false;
} 
// 注意基本类型可以直接比较,但引用类型最好调用其equal方法
Card c = (Card)o;
return rank == c.rank
&& suit.equals(c.suit);
 }
}

注意: 一般覆写 equals 的套路就是上面演示的
1. 如果指向同一个对象,返回 true
2. 如果传入的为 null,返回 false
3. 如果传入的对象类型不是 Card,返回 false
4. 按照类的实现目标完成比较,例如这里只要花色和数值一样,就认为是相同的牌
5. 注意下调用其他引用类型的比较也需要 equals,例如这里的 suit 的比较
覆写基类equal的方式虽然可以比较,但缺陷是:equal只能按照相等进行比较,不能按照大于、小于的方式进行比较。

1.3引用对象基于Comparble接口类的比较

Comparble是JDK提供的泛型的比较接口类,源码实现具体如下:

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

 

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

class Student implements Comparable<Student>{
    public int age;
    public String name;

    public Student(String name,int age) {
        this.name = name;
        this.age = age;

    }
@Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }
}
public static void main(String[] args) {
  Student student1 = new Student("zhangsan",10);
  Student student2 = new Student("zhangsan",20);
  System.out.println(student1 == student2);
  System.out.println(student1.equals(student2));
  System.out.prinln(student1.compareTo(student2));
}

Compareble是java.lang中的接口类,可以直接使用。

 1.4引用对象基于比较器的比较

对于引用对象,我们还可以用比较器进行比较:用户自定义比较器类,实现Comparator接口

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

注意:区分Comparable和Comparator。

import java.util.Comparator;
import java.util.Objects;

class Student implements {
    public int age;
    public String name;

    public Student(String name,int age) {
        this.name = name;
        this.age = age;

    }

class NameComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
    if (o1 == o2) {
    return 0;
    } 
    if(o1 == null) {
    return -1;
    }
    if(o2 == null) {
    return -1;
    }
        return o1.name.compareTo(o2.name);
    }
}

class AgeComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {

    if (o1 == o2) {
    return 0;
    } 
    if(o1 == null) {
    return -1;
    }
    if(o2 == null) {
    return -1;
    }

        return o2.age - o1.age;
    }
}



public static void main(String[] args) {
        Student student1 = new Student("zhangsan",10);
        Student student2 = new Student("zhangsan",20);
        // 定义比较器对象
        NameComparator nameComparator = new NameComparator();
        int ret = nameComparator.compare(student1,student2);
        System.out.println(ret);
        // 使用比较器对象进行比较
        AgeComparator ageComparator = new AgeComparator();
        int ret2 = ageComparator.compare(student1,student2);
        System.out.println(ret2);
}

注意:Comparator是java.util 包中的泛型接口类,使用时必须导入对应的包.

1.5三种方式的对比

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

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

2.1PriorityQueue中的比较方式

集合框架中的PriorityQueue底层使用堆结构,因此其内部的元素必须要能够比大小,PriorityQueue采用了:
Comparble和Comparator两种方式。
1. Comparble是默认的内部比较方式,如果用户插入自定义类型对象时,该类对象必须要实现Comparble接口,并覆写compareTo方法
2. 用户也可以选择使用比较器对象,如果用户插入自定义类型对象时,必须要提供一个比较器类,让该类实现Comparator接口并覆写compare方法。

 

 

 

 

 向上调整:
 如果用户没有提供比较器对象,采用Comparable进行比较
 否则使用用户提供的比较器对象进行比较

 使用Comparable举个例子:

class Student implements Comparable<Student>{
    public int age;
    public String name;

    public Student(String name,int age) {
        this.name = name;
        this.age = age;

    }

class AgeComparator implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        return o2.age - o1.age;
    }
}

public class Test {
    public static void main(String[] args) {
        AgeComparator ageComparator = new AgeComparator();
        Queue<Student> priorityQueue2 = new PriorityQueue<>(ageComparator);
        priorityQueue2.offer(new Student("zhangsan",27));
        priorityQueue2.offer(new Student("lisi",15));
        priorityQueue2.poll();
}
}

在PriorityQueue中按降序进行排序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/168400.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用云端的GPU进行yolov5的训练

前言本文介绍了使用云端GPU进行yolov5训练环境配置的过程一、创建实例这里使用的是恒源云的GPU服务器&#xff0c;官方网址为恒源云_GPUSHARE-恒源智享云他的用户文档为Tmux - 恒源云用户文档一般的问题在用户文档中都可以找到解决办法。注册并登录后的界面如下图所示。点击云市…

c++11 标准模板(STL)(std::forward_list)(十)

定义于头文件 <forward_list> template< class T, class Allocator std::allocator<T> > class forward_list;(1)(C11 起)namespace pmr { template <class T> using forward_list std::forward_list<T, std::pmr::polymorphic_…

UPerNet:Unified Perceptual Parsing for Scene Understanding论文解读

Unified Perceptual Parsing for Scene Understanding 论文&#xff1a;[1807.10221] Unified Perceptual Parsing for Scene Understanding (arxiv.org) 代码&#xff1a;CSAILVision/unifiedparsing: Codebase and pretrained models for ECCV’18 Unified Perceptual Parsi…

第二章.线性回归以及非线性回归—岭回归

第二章.线性回归以及非线性回归 2.12 岭回归&#xff08;Ridge Regression&#xff09; 1.前期导入&#xff1a; 1).标准方程法[w(XTX)-1XTy]存在的缺陷&#xff1a; 如果数据的特征比样本点还多&#xff0c;数据特征n&#xff0c;样本个数m&#xff0c;如如果n>m&#xf…

5种气血不足的面相

我们常用“气色好”形容人良好的健康状态&#xff0c;反之&#xff0c;气血不足就是不健康的表现。想知道自己是否气血不足&#xff0c;可以从以下几种表现中判断。眼白黄&#xff1a;所谓人老珠黄&#xff0c;就是指眼白的颜色变得浑浊、发黄、有血丝&#xff0c;很可能气血不…

网络编程基础(1)

1 OSI七层模型&#xff08;理论&#xff09; 七层模型&#xff0c;亦称OSI&#xff08;Open System Interconnection&#xff09;。参考模型是国际标准化组织&#xff08;ISO&#xff09;制定的一个用于计算机或通信系统间互联的标准体系&#xff0c;一般称为OSI参考模型或七层…

cycle_gan使用教程

junyanz/pytorch-CycleGAN-and-pix2pix: Image-to-Image Translation in PyTorch (github.com) 如果是用cycle_gan 数据集 /数据集文件夹名&#xff0c;下面四个子文件名 testA testB trainA trainB trainA是A风格图片&#xff0c;trainB是B风格图片。 训练参数 test…

CCF BDCI | 算能赛题决赛选手说明论文-04

基于TPU平台实现人群密度估计 队名&#xff1a;innovation 陈照照 数据科学与大数据技术20级 台州学院 中国-瑞安 479253198qq.com董昊数据科学与大数据技术20级 台州学院 中国-杭州 donghaowifi163.com陈晓聪数据科学与大数据技术20级 台州学院 中国-宁波 2637491…

Golang -- openwechat微信发送消息、自动回复

开篇 马上就要到农历新年了&#xff0c;不妨写一段代码准时为好友们送上祝福。 该 Demo 使用开源项目 openwechat &#xff0c;实现获取好友列表、为好友发送消息、图片或文件&#xff0c;接收来自好友或群组的消息并设置自动回复等功能。 openwechat Github地址 openwechat 文…

管道(匿名,有名)

文章目录Linux 进程间通信的方式管道匿名管道有名管道Linux 进程间通信的方式 管道 管道特点 管道其实是一个在内核内存中维护的缓冲器&#xff0c;这个缓冲器的存储能力是有限的&#xff0c;不同的操作系统大小不一定相同管道拥有文件的特质&#xff1a;读操作、写操作 匿名管…

线扫相机DALSA-变行高拍照

CamExpert在线阵模式中默认的Buffer设置是Fixed Length。在这种设置下&#xff0c;在一帧采集结束前所接收到的新的帧触发信号都会被忽略。在有的应用中&#xff0c;需要新一帧的外触发信号能够中断当前帧的采集&#xff0c;开始新的一帧。这需要将Buffer设为Variable Length。…

【云原生】k8s之HPA,命名空间资源限制

内容预知 1.HPA的相关知识 2.HPA的部署运用 2.1 进行HPA的部署设置 2.2 HPA伸缩的测试演示 &#xff08;1&#xff09;创建一个用于测试的pod资源 (2)创建HPA控制器&#xff0c;进行资源的限制&#xff0c;伸缩管理 &#xff08;3&#xff09;进入其中一个pod容器仲&#xf…

Redhat OpenStack使用命令行发放云主机

OpenStack中各大组件的作用Glance&#xff1a;负责管理镜像&#xff08;镜像的上传、删除、下载&#xff09;Swift&#xff1a;提供镜像存储的空间Nova&#xff1a;负责配额的修改、启动云主机&#xff08;实例&#xff09;、创建密钥对、绑定弹性IP等Keystone&#xff1a;提供…

jQuery(二):属性、元素、尺寸位置操作、事件

jQuery属性操作内容文本值元素操作尺寸、位置操作事件注册事件处理事件对象拷贝对象属性操作 1.获取固有属性语法 prop(‘‘属性’’) 固有属性就是html自带的&#xff0c;例如a元素里面的 href &#xff0c;input 元素里面的 type。 2.设置固有属性语法 prop(‘‘属性’’, …

Python NumPy 搜索 数组

前言NumPy&#xff08;Numerical Python的缩写&#xff09;是一个开源的Python科学计算库。使用NumPy&#xff0c;就可以很自然地使用数组和矩阵。NumPy包含很多实用的数学函数&#xff0c;涵盖线性代数运算、傅里叶变换和随机数生成等功能。本文主要介绍Python NumPy 搜索 数组…

Linux小黑板(8)管道

"让我们,笑吧"一、什么是通信?管道是属于进程间通信的一个实现方式。再讲管道之前呢&#xff0c;我们先来说说什么叫做进程间通信。我们日常生活中&#xff0c;给自己的家人、朋友给一个call&#xff0c;或者弹一条微信、QQ等等&#xff0c;从而让人家能够知道我们想…

Databend 开源周报第 76 期

英文版移步&#xff1a;https://databend.rs/blog/2023-01-11-databend-weekly Databend 是一款强大的云数仓。专为弹性和高效设计。自由且开源。即刻体验云服务&#xff1a;https://app.databend.com 。 What’s New 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的…

vue 中由浅拷贝引发问题的一些场景

在工作的过程中踩了很多的由浅拷贝导致的坑&#xff0c;今天总结在这里&#xff0c;希望对大家有所帮助 1. 组件中直接抛出一个引用类型变量 &#x1f330;举个例子 &#xff08;ps: 以下代码为伪代码&#xff0c;主要展示逻辑用&#xff09; 子组件&#xff08;uploadImg&a…

线 程 同 步、线程的死锁问题

线程同步&#xff1a; 模拟售票程序出现问题&#xff1a;当多个线程同时访问共享数据时&#xff0c;产生无序、重复、超额售票等多线程安全问题 解决&#xff1a;将多个线程需要访问的共享数据&#xff0c;包装起来视为一个整体&#xff0c;确保一次只有一个线程执行流访问共享…

春节福利丨神策数据 2022 年数字化营销资料打包全送

2022 年&#xff0c;神策数据出品多份行业研究报告&#xff0c;覆盖银行、证券、零售、教育、电商、融合媒体等多个行业&#xff0c;帮助更多企业通过多视角洞见紧握数字化营销的方向和趋势&#xff0c;用方法论结合落地实践驱动企业数字化经营。01B2B 电商数字化运营聚焦四类 …