一、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 hashMap = new HashMap();
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
该类需要实现Comparable
必须重写public int compareTo(T o)方法,比如MapReduce中Map函数和Reduce函数处理的
其中需要根据key对键值对进行排序,
所以,key实现了WritableComparable
WritableComparable
3、compare(Object o1,Object o2)方法是java.util.Comparator
举例说明:
新建一个Cat.java类
package com.util.compare;
public class Cat implements Comparable
新建一个测试类: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 COMPARATOR = new Comparator() {
public int compare(Cat o1, Cat o2) {
return o1.compareTo(o2);//运用Cat类的compareTo方法比较两个对象
}
};
public static void main(String[] args) {
ArrayList cat = new ArrayList();
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
三、单独使用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
}