一、概述

程序要对一堆数据元素排序,查找,增加删除。
数据节点

class Node{
int type;
int index;
int score;
}

  

规则:
  1)对象相等:两个节点n1与n2,如果n1.type == n2.type && n1.index == n2.index则n1等于n2
  2)排序:升序,比较score,score相同则比较type,type相同则比较index.
最开始我使用TreeMap存储。实现Comparable接口,重写equals方法与hashCode方法。
如下:

class Node implements Comparable<Node>{
public int type;
public int index;
public int score;
public Node(int t, int u, int s) {
this.type = t;
this.index = u;
this.score = s;
}
@Override
public int compareTo(Node o) {
if(this.score != o.score) return this.score > o.score ? -1 : 1;
else if(this.type != o.type) return this.type - o.type;
else return this.index - o.index;
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
if(this == obj) return true;
if(obj instanceof Node) {
Node tn = (Node) obj;
if(tn.type == this.type && tn.index == this.index) return true;
}
return false;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return this.type + this.index;
}
}

程序一直不对,经过两个小时反复的检查。我意识到,TreeMap比较对象是否相同也是调用CompareTo方法。equals和hashCode是HashMap那一套。
修改后,每个type的数据用一个TreeMap保存。
如下:

class Node implements Comparable<Node>{
public int type;
public int index;
public int score;
public Node(int t, int u, int s) {
this.type = t;
this.index = u;
this.score = s;
}
@Override
public int compareTo(Node o) {
if(this.type == o.type && this.index == o.index) return 0;
else {
if(this.score != o.score) return this.score > o.score ? -1 : 1;
else return this.index - o.index;
}
}
}

最后的排序使用优先队列。
比较器:

Comparetor<Node> cmp = (x, y) ->{
if(x.score != y.score) return x.score > y.score ? -1: 1;
else if(x.type != y.type) return x.type - y.type;
return x.index - y.index;
}

正确使用equals和compareTo,减少bug。

二、重写equals

HashSet中存储自己定义的对象,HashMap使用自定义的对象作Key,都需要重写equals。同时要重写hashCode.
hashCode定位,equals比较对象是否相同。
如下:

@Override
public boolean equals(Object obj) {//参数类型必须为Object,否则无效
// TODO Auto-generated method stub
if(this == obj) return true; //同引用
if(obj instanceof Node) {//obj为null时,条件为假。
Node tn = (Node) obj;
if(tn.type == this.type && tn.index == this.index) return true;//根据内容比较对象
}
return false;
}

hashCode方法要保证相同对象的返回值相同。想实现一个好的hashCode比较难。

三、重写compareTo

有序的集合,存储自定以的对象都需要重写compareTo方法或者提供该对象的比较器。常用到的集合有TreeMap(红黑树)、TreeSet、PriorityQueue(堆)、Arrays::sort(数组排序)、Collections::sort(List排序)。
如下:

class Data implements Comparable<Data>{ //实现Comparable接口
@Override
public int compareTo(Data o) {//小于返回负值,等于返回0,大于返回正值
// TODO Auto-generated method stub
return 0;
}
}

比较器,如下:

Comparator<Node> cmp = new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
// TODO Auto-generated method stub
return 0;
}
};

使用Lambda表达式。

Comparetor<Node> cmp = (x, y) ->{
if(x.score != y.score) return x.score > y.score ? -1: 1;
else if(x.type != y.type) return x.type - y.type;
return x.index - y.index;
}

正确重写equals方法和compareTo方法的更多相关文章

  1. HashSet中存方用户自己定义数据类型数据,重写equals方法和hashCode方法

    import java.util.Set; import java.util.HashSet; public class SetTest { public static void main(Strin ...

  2. JAVA正确地自定义比较对象---如何重写equals方法和hashCode方法

    在实际应用中经常会比较两个对象是否相等,比如下面的Address类,它有两个属性:String province 和 String city. public class Address { priva ...

  3. Hibernate中为什么要重写equals方法和hashcode方法

    1.*为什么要重写equals方法,首先我们来看一下equals源码: public boolean equals(Object anObject) { if (this == anObject) { ...

  4. 对象作为 map 的 key 时,需要重写 equals 方法和 hashCode 方法

    对象作为 map 的 key 时,需要重写 hashCode 和 equals方法 如果没有重写 hashCode 方法,那么下面的代码示例会输出 null 我们首先定义一个对象:BmapPoint, ...

  5. Java重写equals方法和hashCode方法

    package com.ddy; public class User {     private Integer id;     private String name;     private St ...

  6. HashSet中的元素必须重写equals方法和hashCode方法

    http://jingyan.baidu.com/article/d5a880eb8fb61d13f147cc99.html 1.为什么必须重写这两个方法. 2.什么事hashSet去重,符合什么样的 ...

  7. 关于Object类的equals方法和hashCode方法

    关于Object类的equals的特点,对于非空引用: 1.自反性:x.equals(x) return true : 2.对称性:x.equals(y)为true,那么y.equals(x)也为tr ...

  8. Java 如何重写对象的 equals 方法和 hashCode 方法

    前言:Java 对象如果要比较是否相等,则需要重写 equals 方法,同时重写 hashCode 方法,而且 hashCode 方法里面使用质数 31.接下来看看各种为什么. 一.需求: 对比两个对 ...

  9. 详解equals()方法和hashCode()方法

    前言 Java的基类Object提供了一些方法,其中equals()方法用于判断两个对象是否相等,hashCode()方法用于计算对象的哈希码.equals()和hashCode()都不是final方 ...

随机推荐

  1. 开园第一篇---有关tensorflow加载不同模型的问题

    写在前面 今天刚刚开通博客,主要想法跟之前某位博主说的一样,希望通过博客园把每天努力的点滴记录下来,也算一种坚持的动力.我是小白一枚,有啥问题欢迎各位大神指教,鞠躬~~ 换了新工作,目前手头是OCR项 ...

  2. javaScript今日总结

    javascript简单介绍ECMAScript 1.语法 2.变量:只能使用var定义,如果在函数的内容使用var定义,那么它是一个局部变量,如果没有使用var它是一个全局的.弱类型! 3.数据类型 ...

  3. CentOS7.x 搭建 GitLab 教程

    今天闲来无事,想起之前买了一个阿里云 ECS,一直闲置着没用,一时兴起就想搭个自己的 GitLab 玩玩,GitLab 官网也提供了安装教程,很简单,照着步骤一步步基本没什么问题,可能安装的过程中有一 ...

  4. win10 将硬盘工作模式由IDE调整到AHCI模式

    第1步:重启进入安全模式 1)点击“开始”按钮 进入设置 2)进入“更新和安全”,“恢复-高级启动”,点击“立即高级启动”, 依次选择“疑难解答”-“高级选项”-“启动设置”-点击“重启” 第2步:进 ...

  5. HTML文件上传与下载

    文件下载 传统的文件下载有两种方法: 使用<a/>标签,href属性直接连接到服务器的文件路径 window.location.href="url" 这两种方法效果一样 ...

  6. keras 学习笔记:从头开始构建网络处理 mnist

    全文参考 < 基于 python 的深度学习实战> import numpy as np from keras.datasets import mnist from keras.model ...

  7. pip安装时使用国内源,加快下载速度

    国内源: 新版ubuntu要求使用https源,要注意. 清华:https://pypi.tuna.tsinghua.edu.cn/simple 阿里云:http://mirrors.aliyun.c ...

  8. (通俗易懂小白入门)字符串Hash+map判重——暴力且优雅

    字符串Hash 今天我们要讲解的是用于处理字符串匹配查重的一个算法,当我们处理一些问题如给出10000个字符串输出其中不同的个数,或者给一个长度100000的字符串,找出其中相同的字符串有多少个(这样 ...

  9. Centos知识

    1.看系统的版本: cat /etc/redhat-release 2.看内核版本: uname -r 3.查看系统是32位还是64位 uname - m 4.磁盘: 磁盘分区有主分区.扩展分区和逻辑 ...

  10. Java网络编程 -- NIO非阻塞网络编程

    从Java1.4开始,为了替代Java IO和网络相关的API,提高程序的运行速度,Java提供了新的IO操作非阻塞的API即Java NIO.NIO中有三大核心组件:Buffer(缓冲区),Chan ...