一、概述

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

  1. class Node{
  2. int type;
  3. int index;
  4. int score;
  5. }

  

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

  1. class Node implements Comparable<Node>{
  2. public int type;
  3. public int index;
  4. public int score;
  5. public Node(int t, int u, int s) {
  6. this.type = t;
  7. this.index = u;
  8. this.score = s;
  9. }
  10. @Override
  11. public int compareTo(Node o) {
  12. if(this.score != o.score) return this.score > o.score ? -1 : 1;
  13. else if(this.type != o.type) return this.type - o.type;
  14. else return this.index - o.index;
  15. }
  16. @Override
  17. public boolean equals(Object obj) {
  18. // TODO Auto-generated method stub
  19. if(this == obj) return true;
  20. if(obj instanceof Node) {
  21. Node tn = (Node) obj;
  22. if(tn.type == this.type && tn.index == this.index) return true;
  23. }
  24. return false;
  25. }
  26. @Override
  27. public int hashCode() {
  28. // TODO Auto-generated method stub
  29. return this.type + this.index;
  30. }
  31. }

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

  1. class Node implements Comparable<Node>{
  2. public int type;
  3. public int index;
  4. public int score;
  5. public Node(int t, int u, int s) {
  6. this.type = t;
  7. this.index = u;
  8. this.score = s;
  9. }
  10. @Override
  11. public int compareTo(Node o) {
  12. if(this.type == o.type && this.index == o.index) return 0;
  13. else {
  14. if(this.score != o.score) return this.score > o.score ? -1 : 1;
  15. else return this.index - o.index;
  16. }
  17. }
  18. }

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

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

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

二、重写equals

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

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

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

三、重写compareTo

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

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

比较器,如下:

  1. Comparator<Node> cmp = new Comparator<Node>() {
  2. @Override
  3. public int compare(Node o1, Node o2) {
  4. // TODO Auto-generated method stub
  5. return 0;
  6. }
  7. };

使用Lambda表达式。

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

正确重写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. Myeclipse8.5上基于JAX-WS开发WebService

    1.JAX-WS介绍 JAX-WS规范是一组XML web services的JAVA API. 2.开发步骤 基于JAX-WS的WebService开发步骤如下: 2.1 新建一个Web Servi ...

  2. Linux系统上安装OpenOffice

    项目需求需要在linux上安装openOffice,本以为很简单,现在看来还是入了很多坑.理清楚就好了. 官网地址 http://download.openoffice.org/other.html ...

  3. element ui 登录验证,路由守卫

    <template> <!-- el-form :label-position="labelPosition" 设置label的位置 :model 用来给表单设置 ...

  4. VMware安装Centos7虚拟机

    首先安装虚拟机很简单,所以呢,具体的安装过程就引用别人的博客,这篇文字很详细,引用之后会在后面加上一些遇到的问题: 原文:https://blog.csdn.net/babyxue/article/d ...

  5. Netty源码分析--内存模型(下)(十二)

    这一节我们一起看下分配过程 PooledByteBuf<T> allocate(PoolThreadCache cache, int reqCapacity, int maxCapacit ...

  6. Delegate,Block,Notification, KVC,KVO,Target-Action

    Target-Action: 目标-动作机制,所有的UIControl及子类都是这个机制:原理:在对象产生某个事件的特定时刻,给一个对象发送一个消息:类内部target去执行action方法 Dele ...

  7. nessus安装

    1.安装注册 (1)从https://www.tenable.com/products/nessus/select-your-operating-system上下载对应操作系统版本的nessus,结果 ...

  8. 图数据库 Nebula Graph 的数据模型和系统架构设计

    Nebula Graph:一个开源的分布式图数据库.作为唯一能够存储万亿个带属性的节点和边的在线图数据库,Nebula Graph 不仅能够在高并发场景下满足毫秒级的低时延查询要求,而且能够提供极高的 ...

  9. Spring Context 你真的懂了吗

    今天介绍一下大家常见的一个单词 context 应该怎么去理解,正确的理解它有助于我们学习 spring 以及计算机系统中的其他知识. 1. context 是什么 我们经常在编程中见到 contex ...

  10. AVL树(二叉平衡树)详解与实现

    AVL树概念 前面学习二叉查找树和二叉树的各种遍历,但是其查找效率不稳定(斜树),而二叉平衡树的用途更多.查找相比稳定很多.(欢迎关注数据结构专栏) AVL树是带有平衡条件的二叉查找树.这个平衡条件必 ...