HashSet TreeSet 和 equals、hashCode、comparable接口之间关联

来源:互联网 发布:周婷katiechow的淘宝 编辑:程序博客网 时间:2024/05/16 15:05
HashSet HashMap HashTable:内部采用哈希表实现

TreeSet TreeMap:排序,利用 compareTo或者comparator比较功能实现

 问题思考:在HashSet添加 new BigDecimal(“1.0”)和new BigDecimal(“1.00”)两个都添加!而在TreeSet添加 new BigDecimal(“1.0”)和new BigDecimal(“1.00”) 却只添加一个?这是为什么?

HashSet判断两个元素是否相等,HashSet判断两个元素是否相同是通过equals来实现的,但是如果全部扫描一遍则时间复杂度为O(n),为了提高效率采用hash表实现,而hash表查找是根据hashcode比较来实现的。所以为了HashSet能够正常工作,两个逻辑相等equals的对象hashcode必须相等,所以覆盖了equas方法必须同时覆盖hashcode方法。

TreeSet实现了排序。要排序就必须能够对两个对象进行比较,这就要求比较的对象必须实现Comparable接口(其中包含compareTo方法)。

 关于Equals方法和compareTo方法的实现:

(1)共同点:实现的功能差不多,都是对原有方法进行覆盖。但是Equals方法是来自于Object最原始的类,而compareTo是来自于Comparable接口。基本思想就是将对象内部的各部分进行比较,若都相同则判定相等。

(2)不同点:

public boolean equals(Object obj) ;

public int compareTo(PhoneNum o);

很多人覆盖equals用的参数是MyClass自己的类,必须得是Object类,否则不会进行覆盖override,而是重载overload!

Equals方法的通用过程:

1)用’==’判断是否同一对象的引用

2)使用instanceof或者getClass判断是否同一类型

3)将Object转化为正确类型

4)对该类中的关键域进行逐个比较,判断是否相等

package com.zgd;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.Map.Entry;import java.util.Set;class PhoneNum implements Comparable<PhoneNum>{private int areaNum;private int numPart1;private int numPart2;public int getAreaNum() {return areaNum;}public void setAreaNum(int areaNum) {this.areaNum = areaNum;}public int getNumPart1() {return numPart1;}public void setNumPart1(int numPart1) {this.numPart1 = numPart1;}public int getNumPart2() {return numPart2;}public void setNumPart2(int numPart2) {this.numPart2 = numPart2;}@Overridepublic String toString() {return "PhoneNum [areaNum=" + areaNum + ", numPart1=" + numPart1+ ", numPart2=" + numPart2 + "]";}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + areaNum;result = prime * result + numPart1;result = prime * result + numPart2;return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())//防止因为是子类而带来的问题return false;PhoneNum other = (PhoneNum) obj;if (areaNum != other.areaNum)//这里因为实在这个函数里面,所以可以直接引用?return false;if (numPart1 != other.numPart1)return false;if (numPart2 != other.numPart2)return false;return true;}public PhoneNum(int areaNum, int numPart1, int numPart2) {super();this.areaNum = areaNum;this.numPart1 = numPart1;this.numPart2 = numPart2;}@Overridepublic int compareTo(PhoneNum o) {// TODO Auto-generated method stubif(areaNum - o.getAreaNum() != 0){return areaNum - o.getAreaNum() ;}if(numPart1 - o.numPart1 != 0){return numPart1 - o.numPart1 ;}if(numPart2 - o.numPart2 != 0){return numPart2 - o.numPart2;}return 0;}}public class Test {public static void main(String[] args) {// TODO Auto-generated method stub//SetSet<PhoneNum> set_pn = new HashSet<PhoneNum>();set_pn.add(new PhoneNum(101,13811,320857));set_pn.add(new PhoneNum(103,13813,320859));set_pn.add(new PhoneNum(102,13814,320858));PhoneNum pn = new PhoneNum(101,13811,320857);PhoneNum pn2 = new PhoneNum(105,13811,320857);////for(PhoneNum pn : set_pn){//System.out.println(pn.toString());//}Map<PhoneNum,String> map = new HashMap<PhoneNum,String>();map.put(new PhoneNum(101,13811,320857), "zenggd");map.put(new PhoneNum(103,13813,320859), "guodong");map.put(new PhoneNum(102,13812,320858), "harry");for(Map.Entry<PhoneNum, String> tt: map.entrySet()){System.out.println(tt.getKey() + " " + tt.getValue());}//List<Map.Entry<PhoneNum, String>> list= new ArrayList<Map.Entry<PhoneNum, String>>();//list.addAll(map.entrySet());////Map.Entry<PhoneNum, String> temp = Collections.max(list, new Comparator<Map.Entry<PhoneNum, String>>() {////@Override//public int compare(Entry<PhoneNum, String> o1,//Entry<PhoneNum, String> o2) {//// TODO Auto-generated method stub//return o1.getKey().getAreaNum() - o2.getKey().getAreaNum();////return 0;//}////});////System.out.println(temp.getKey());//for(PhoneNum pn_temp : map.keySet()){////System.out.println(pn_temp+" "+map.get(pn_temp));//}////List//PhoneNum tt = Collections.max(set_pn,new Comparator<PhoneNum>() {////@Override//public int compare(PhoneNum o1, PhoneNum o2) {//// TODO Auto-generated method stub//if(o1.getNumPart1() - o2.getNumPart2() != 0){//return o1.getNumPart1() - o2.getNumPart2();//}////if(o1.getAreaNum() - o2.getAreaNum() != 0){//return o1.getAreaNum() - o2.getAreaNum() ;//}//return 0;//}//});////System.out.println(Float.floatToIntBits(3.444f));//System.out.println(Float.floatToIntBits(3.443f));//System.out.println(Float.compare(0.2f, 2.3f));//Map}}

下面是eclipse自动生成的equals方法:

@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;PhoneNum other = (PhoneNum) obj;if (areaNum != other.areaNum)//other可以直接引用private属性return false;if (numPart1 != other.numPart1)return false;if (numPart2 != other.numPart2)return false;return true;}
其中 Map.Entry<U,V>   相当于Map中的一个映射
原创粉丝点击