数据结构与算法:java对象的比较

news2024/11/28 10:46:22

1.基本类型的比较

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

public class TestCompare {
	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);
	}
}

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指向的是同一个对象
	}
}

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

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

有些情况下,需要比较的是对象中的内容,有三种方式对比:

1.覆写基类的equals

public class Card {
	public int rank; // 数值
	public String suit; // 花色
	public Card(int rank, String suit) {
		this.rank = rank;
		this.suit = suit;
}

@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只能按照相等进行比较,不能按照大于、小于的方式进行比较。

2.基于Comparble接口类的比较

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

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

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

public class Card implements Comparable<Card> {
	public int rank; // 数值
	public String suit; // 花色
	public Card(int rank, String suit) {
		this.rank = rank;
		this.suit = suit;
}

// 根据数值比较,不管花色
// 这里我们认为 null 是最小的
@Override
public int compareTo(Card o) {
	if (o == null) {
		return 1;
	}
	return rank - o.rank;
}

public static void main(String[] args){
	Card p = new Card(1, "♠");
	Card q = new Card(2, "♠");
	Card o = new Card(1, "♠");
	System.out.println(p.compareTo(o)); // == 0,表示牌相等
	System.out.println(p.compareTo(q)); // < 0,表示 p 比较小
	System.out.println(q.compareTo(p)); // > 0,表示 q 比较大
	}
}

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

3.基于比较器比较

  • 用户自定义比较器类,实现Comparator接口:
public interface Comparator<T> {
	// 返回值:
	// < 0: 表示 o1 指向的对象小于 o2 指向的对象
	// == 0: 表示 o1 指向的对象等于 o2 指向的对象
	// > 0: 表示 o1 指向的对象等于 o2 指向的对象
	int compare(T o1, T o2);
}

注意:区分Comparable和Comparator。

  • 覆写Comparator中的compare方法
import java.util.Comparator;
class Card {
    public int rank; // 数值
    public String suit; // 花色
    public Card(int rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }
}

class CardComparator implements Comparator<Card> {
// 根据数值比较,不管花色
// 这里我们认为 null 是最小的
    @Override
    public int compare(Card o1, Card o2) {
        if (o1 == o2) {
            return 0;
        }
        if (o1 == null) {
            return -1;
        }
        if (o2 == null) {
            return 1;
        }
        return o1.rank - o2.rank;
    }
    public static void main(String[] args) {
        Card p = new Card(1, "♠");
        Card q = new Card(2, "♠");
        Card o = new Card(1, "♠");
		// 定义比较器对象
        CardComparator cmptor = new CardComparator();
		// 使用比较器对象进行比较
        System.out.println(cmptor.compare(p, o)); // == 0,表示牌相等
        System.out.println(cmptor.compare(p, q)); // < 0,表示 p 比较小
        System.out.println(cmptor.compare(q, p)); // > 0,表示 q 比较大
    }
}

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

在这里插入图片描述

3.集合框架中PriorityQueue的比较方式

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

  1. Comparble是默认的内部比较方式,如果用户插入自定义类型对象时,该类对象必须要实现Comparble接口,并覆写compareTo方法。
  2. 用户也可以选择使用比较器对象,如果用户插入自定义类型对象时,必须要提供一个比较器类,让该类实现Comparator接口并覆写compare方法。
// JDK中PriorityQueue的实现:
public class PriorityQueue<E> extends AbstractQueue<E>
    implements java.io.Serializable {
	// ...
	// 默认容量
    private static final int DEFAULT_INITIAL_CAPACITY = 11;
	// 内部定义的比较器对象,用来接收用户实例化PriorityQueue对象时提供的比较器对象
    private final Comparator<? super E> comparator;
	// 用户如果没有提供比较器对象,使用默认的内部比较,将comparator置为null
    public PriorityQueue() {
        this(DEFAULT_INITIAL_CAPACITY, null);
    }
	// 如果用户提供了比较器,采用用户提供的比较器进行比较
    public PriorityQueue(int initialCapacity, Comparator<? super E> comparator) {
		// Note: This restriction of at least one is not actually needed,
		// but continues for 1.5 compatibility
        if (initialCapacity < 1)
            throw new IllegalArgumentException();
        this.queue = new Object[initialCapacity];
        this.comparator = comparator;
    }
	// ...
	// 向上调整:
	// 如果用户没有提供比较器对象,采用Comparable进行比较
	// 否则使用用户提供的比较器对象进行比较
    private void siftUp(int k, E x) {
        if (comparator != null)
            siftUpUsingComparator(k, x);
        else
            siftUpComparable(k, x);
    }
	// 使用Comparable
    @SuppressWarnings("unchecked")
    private void siftUpComparable(int k, E x) {
        Comparable<? super E> key = (Comparable<? super E>) x;
        while (k > 0) {
            int parent = (k - 1) >>> 1;
            Object e = queue[parent];
            if (key.compareTo((E) e) >= 0)
                break;
            queue[k] = e;
            k = parent;
        }
        queue[k] = key;
    }
	// 使用用户提供的比较器对象进行比较
    @SuppressWarnings("unchecked")
    private void siftUpUsingComparator(int k, E x) {
        while (k > 0) {
            int parent = (k - 1) >>> 1;
            Object e = queue[parent];
            if (comparator.compare(x, (E) e) >= 0)
                break;
            queue[k] = e;
            k = parent;
        }
        queue[k] = x;
    }
}

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

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

相关文章

互联网舆情监测公司监测哪些内容,TOOM北京舆情监测公司

互联网舆情监测公司是一种提供舆情监测、分析和管理服务的公司&#xff0c;其业务主要涉及互联网舆情监测、数据分析、报告撰写、危机处理等方面。这些公司通过使用各种技术和工具&#xff0c;帮助客户监测他们在互联网上的声誉和品牌形象&#xff0c;并提供相应的建议和解决方…

前端基于 Docker 的 SSR 持续开发集成环境实践

项目收益 整体开发效率提升20%。加快首屏渲染速度&#xff0c;减少白屏时间&#xff0c;弱网环境下页面打开速度提升40%。 权衡 在选择使用SSR之前&#xff0c;需要考虑以下事项&#xff01; SSR需要可以运行Node.js的服务器&#xff0c;学习成本相对较高。对于服务器而言&a…

“就业”or“创业”,大学生毕业如何选择,校园市场是新出路?

据公开数据显示&#xff0c;2023届全国高校毕业生预计达到1158万人&#xff0c;同比增加82万人。规模和增量创历史新高。今年就业形势再次复杂严峻起来。 “就业难”这个词在疫情下的毕业季尤为明显。超过1000万人同时加入了争夺就业机会的行列&#xff0c;形成了庞大的求职阵容…

网络安全-靶场搭建

网络安全-靶场搭建 靶场就是给你练习用的&#xff0c;因为如果你直接用其他网站搞会把他搞炸的&#xff08;犯法的&#xff09; 简单概括&#xff1a;把靶场文件放到Phpstudy的网站&#xff0c;放到根目录里面 要用到之前下载的phpstudy 然后开启mysql和apache&#xff0c;默…

【2023】Prometheus-Blackbox_exporter使用

目录1.下载及安装blackbox_exporter2.修改配置文件设置监控内容2.1.使用http方式作为探测3.与prometheus集成4.导入blackbox仪表盘进行观测1.下载及安装blackbox_exporter 下载安装包 wget https://github.com/prometheus/blackbox_exporter/releases/download/v0.23.0/black…

企业现代化管理模式中,数据指标体系是什么

当前时代&#xff0c;数据已经成为了构建现代社会的重要元素&#xff0c;渗透到人们生活的方方面面。在商业世界中&#xff0c;数据的传播应用更是按下了加速键&#xff0c;在短时间内就让各行各业的企业开始围绕数据进行信息化、数字化转型&#xff0c;把数据当作企业重要的战…

前端原生 CSS 跑马灯效果,无限轮播(横竖版本,带渐变遮罩,简单实用)

一、横版跑马灯 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-wid…

Redis入门到实战-数据结构 (四、原理篇)

一、动态字符串SDS 我们都知道Redis中保存的Key是字符串&#xff0c;value往往是字符串或者字符串的集合。可见字符串是Redis中最常用的一种数据结构。 不过Redis没有直接使用C语言中的字符串&#xff0c;因为C语言字符串存在很多问题&#xff1a; 获取字符串长度的需要通过…

计算机网络之http07 http2,http3

HTTP1.2 http1.2都做了哪些优化 (1)头部压缩 使用HPACK压缩头部 头部冗长&#xff0c;大量重复字段 &#xff08;2&#xff09;二进制帧 将报文头部和内容字符编码改为二进制格式 字符编码未压缩 &#xff08;3&#xff09;并发传输 解决h1.1 队头阻塞问题&#xff0c;多车道 …

opencv通道的分离与合并

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…

腾讯云 cos 字体在CDN上跨域处理

问题描述&#xff1a;项目中用到了字体的静态资源&#xff0c;把静态资源放到了腾讯云对象存储提供的 COS 上&#xff0c;同时启用它的CDN来加速。但是&#xff0c;调试的过程中发现报错&#xff1a;CSS加载字体跨域了&#xff0c;字体图标无法正常显示。 原因&#xff1a;字体…

torch.grid_sample

参考&#xff1a; 双线性插值的理论Pytorch grid_sample解析PyTorch中grid_sample的使用方法pytorch中的grid_sample()使用 查阅官方文档&#xff0c;TORCH.NN.FUNCTIONAL.GRID_SAMPLE grid_sample的函数签名如下所示&#xff0c;torch.nn.functional.grid_sample(input, gr…

Java设计模式总叙

文章目录基本概念设计模式的七大原则设计模式有哪些高频使用&经典的设计模式创建型-工厂方法模式创建型-建造者模式结构型-代理模式结构型-外观模式行为型-策略模式行为型-模板方法补充UML类图关系参考基本概念 使得代码编写真正工程化&#xff0c;它是软件工程的基石。 …

【cuda入门系列】通过代码真实打印线程ID

【cuda入门系列】通过代码真实打印线程ID1.gridDim(6,1),blockDim(4,1)2.gridDim(3,2),blockDim(2,2)【cuda入门系列之参加CUDA线上训练营】在Jetson nano本地跑 hello cuda&#xff01; 【cuda入门系列之参加CUDA线上训练营】一文认识cuda基本概念 【cuda入门系列之参加CUDA线…

ubuntu 20使用kubeadm安装k8s 1.26

步骤 机器&#xff1a;4核8G&#xff0c;root账号&#xff0c;可访问互联网 1、更新apt apt-get update 2、安装一些基本工具 apt-get install ca-certificates curl gnupg lsb-release net-tools apt-transport-https 3、ifconfig 获取ip&#xff0c;hostname获取主机名&…

【洛谷】P1195 口袋的天空

明显看出为最小生成树&#xff0c;那么&#xff1a;难点在哪里呢&#xff1f;if(cntn-k)//******{flag1;break;}为什么是cntn-k呢而不是k呢&#xff1f;&#xff01;&#xff01;&#xff01;解释&#xff1a;&#xff08;如果每个已经连在一起了就不能分开&#xff0c;不管多少…

【Kafka】【二十二】Kafka中Controller,Rebalance,HW,LEO的概念

Kafka中Controller&#xff0c;Rebalance&#xff0c;HW&#xff0c;LEO的概念 Controller 集群中谁来充当controller 每个broker启动时会向zk创建⼀个临时序号节点&#xff0c;获得的序号最⼩的那个broker将会作为集群中的controller&#xff0c;负责这么⼏件事&#xff1a;…

基于距离模型SE

知识表示 one-hot representation: 将研究对象表示为向量&#xff0c;该向量只有某一维度非零&#xff0c;其他维度上的值均为零。独热表示是信息检索和搜索引擎中广泛使用的词袋模型的基础&#xff0c;优点是无需学习过程。简单高效&#xff0c;在信息检索和自然语言处理中得…

亚马逊云科技助力滴普科技,加速企业数据价值洞察

随着企业数字化转型的不断深入&#xff0c;数据对于业务的价值和重要性也逐渐凸显。越来越多企业意识到&#xff0c;只有不断提升底层数据基础平台的性能和能力&#xff0c;才能构建数据驱动的业务&#xff0c;增强企业核心竞争力。作为湖仓一体数据智能基础软件独角兽企业&…

开学必备数码清单,大学生开学必备数码好物分享

还有很多小伙伴不知道开学应该准备什么&#xff0c;在学校当中需要用到的数码产品&#xff0c;在宿舍娱乐使用的音箱、学习当中使用到的笔记本&#xff0c;这些都是我们可以准备的&#xff0c;还有一个小众的好物&#xff0c;能够让我们在学校当中提升生活的幸福感&#xff0c;…