您的位置:首页 > 其它

hashcode、equals和compareTo、compare方法的意义及作用

2016-03-10 16:35 357 查看
一、hashcode和equals必须同时在类中重写(让equals方法和hashCode方法始终在逻辑上保持一致性)

import java.util.HashMap;

class Dog {

private String name;

private Integer age;

public Dog(){}

public Dog(String name, Integer age) {

this.name = name;

this.age = age;

}

//重写hashCode方法,比较hash值(hash值是哈希表中的数据)

//哈希表是一种数据结构,它提供了快速的插入操作和查找操作。其基于数组来实现。

@Override

public int hashCode() {

final int prime = 31;

int result = 1;

result = prime * result + ((age == null) ? 0 : age.hashCode());

result = prime * result + ((name == null) ? 0 : name.hashCode());

return result;

}

//重写equals方法

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

Dog other = (Dog) obj;

if (age == null) {

if (other.age != null)

return false;

} else if (!age.equals(other.age))

return false;

if (name == null) {

if (other.name != null)

return false;

} else if (!name.equals(other.name))

return false;

return true;

}

}

public class HashCodeAndEqualsInfo{

/**

* 测试

* 对于两个对象,如果调用equals方法得到的结果为true,则两个对象的hashcode值必定相等;

* 如果equals方法得到的结果为false,则两个对象的hashcode值不一定不同;

* 但是

* 如果两个对象的hashcode值不等, 则equals方法得到的结果必定为false;

* 如果两个对象的hashcode值相等, 则equals方法得到的结果未知

*

*/

public static void main(String args[]){

/**

* 在HashSet、HashMap以及HashTable插入操作中,类中数据如果是String类型,一定需要实现hashCode和equals方法

*/

Dog dog = new Dog("Marry", 22);

System.out.println("hashCode:"+dog.hashCode());

HashMap<Dog, Integer> hashMap = new HashMap<Dog, Integer>();

hashMap.put(dog, 36);

//如果没有重写hashCode或者equals方法,那么打印null而不是36;

/**原因是没有重写hashCode方法,那么会认为name和age是指向同一个地址即hash值是:33311724

* 如果重写了hashCode和equals方法,那么打印结果是:74115696

*/

System.out.println("结果:"+hashMap.get(new Dog("Marry", 22)));

}

}

二、compareTo方法和compare的意义及作用

1、普通的类要实现排序,必须实现Comparable接口,并重写CompareTo()方法。

2、compareTo(Object o)方法是java.lang.Comparable<T>接口中的方法,当需要对某个类的对象进行排序时,

该类需要实现Comparable<T>接口的,

必须重写public int compareTo(T o)方法,比如MapReduce中Map函数和Reduce函数处理的 <key,value>,

其中需要根据key对键值对进行排序,

所以,key实现了WritableComparable<T>接口,实现这个接口可同时用于序列化和反序列化。

WritableComparable<T>接口 (用于序列化和反序列化)是Writable接口和Comparable<T>接口的组合;

3、compare(Object o1,Object o2)方法是java.util.Comparator<T>接口的方法,它实际上用的是待比较对象的compareTo(Object o)

举例说明:

新建一个Cat.java类

package com.util.compare;

public class Cat implements Comparable<Object>{

int id; //id

String name; //name

public Cat(int id,String name){

this.id = id;

this.name = name;

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

/**

* 重写compareTo方法

*/

@Override

public int compareTo(Object o) {

if(this ==o){

return 0;

}

else if (o!=null && o instanceof Cat) {

Cat u = (Cat) o;

if(id<=u.id){

return -1;

}else{

return 1;

}

}else{

return -1;

}

}

}

新建一个测试类:TestClass.java

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

public class TestClass {

//编写Comparator,根据Cat的id对Cat进行排序

private static final Comparator<Cat> COMPARATOR = new Comparator<Cat>() {

public int compare(Cat o1, Cat o2) {

return o1.compareTo(o2);//运用Cat类的compareTo方法比较两个对象

}

};

public static void main(String[] args) {

ArrayList<Cat> cat = new ArrayList<Cat>();

Cat c1 = new Cat(1,"xiaohei");

Cat c2 = new Cat(2,"xiaohei");

cat.add(c1);

cat.add(c2);

Collections.sort(cat, COMPARATOR);//使用我们写好的Comparator对cat进行排序

//如果是数组排序则使用:Arrays.sort(数组名);

for(int i=0;i<cat.size();i++){

System.out.println("结果:"+cat.get(i).getId());

}

}

}

三、单独使用CompareTo方法

@Test

public void testCpm(){

/**compareTo()的返回值是整型,它是先比较对应字符的大小(ASCII码顺序),

* 如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的差值

* 如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,

* 以此类推,直至比较的字符或被比较的字符有一方全都比较完,这时就比较字符的长度.

* 结论:compareTo比较一定要比较出差值!

* 如果字符串的ascll都比较完,但str和mes中的每一个字符还是相等,

* 那么就比较字符串长度的差值(如str6和mes6比较)

*/

String str="a"; String mes="b";

String str2="abc"; String mes2="a";

String str3="abdc"; String mes3="2d";

String str4="abcde"; String mes4="ab";

String str5="acd"; String mes5="2br";

String str6="acd"; String mes6="acd";

/**a的ascll码是97,1的ascll码是49*/

System.out.println("结果一:"+str.compareTo(mes)); //-1

System.out.println("结果二:"+str2.compareTo(mes2)); //2

System.out.println("结果三:"+str3.compareTo(mes3)); //47

System.out.println("结果四:"+str4.compareTo(mes4)); //3

System.out.println("结果五:"+str5.compareTo(mes5)); //47

System.out.println("结果六:"+str6.compareTo(mes6)); //0

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: