作題總結(二)

1.有如下代碼: java

class A{
    public A(String str){
         
    }
}
public class Test{
    public static void main(String[] args) {
        A classa=new A("he");
        A classb=new A("he");
        System.out.println(classa==classb);
    }
}

輸出是什麼?數組

答案:false多線程

即使是System.out.println(classa.equals(classb));也是false。 由於equals這個方法沒有重寫。併發

##關於重寫equals方法:this

①爲何要重寫equals方法:spa

  默認equals在比較兩個對象時,是看他們是否指向同一個地址的。當一個類有本身特有的「邏輯相等」概念,好比一個People類,包含id和name兩個屬性,咱們想只要id和name同時相等的時候就斷定爲equal,可是不重寫equals方法是作不到的。
package test01;
class People{
    int id;
    String name;
    public People(int id,String name){
        this.id=id;
        this.name=name;
    }
}
public class t5 {
    public static void main(String[] args) {
        People people1=new People(123,"jia");
        People people2=new People(123,"jia");
        System.out.println(people1.equals(people2));
        
    }
}

這樣輸出爲「false」線程

package test01;
class People{
    int id;
    String name;
    public People(int id,String name){
        this.id=id;
        this.name=name;
    }
    public boolean equals(Object obj){
        if(obj instanceof People){
            People p=(People)obj;
            return p.id==id&&p.name.equals(name);
        }
        if(this==obj){
            return true;
        }
        if(this==null)
            return false;
        return false;
    }
}
public class t5 {
    public static void main(String[] args) {
        People people1=new People(123,"jia");
        People people2=new People(123,"jia");
        System.out.println(people1.equals(people2));
        
    }
}

重寫equals方法以後,這樣的輸出爲true。code

可是看看下面一段代碼: 對象

package test01;

import java.util.HashMap;
import java.util.Iterator;

class People{
    int id;
    String name;
    public int getId() {
        return id;
    }
    public String getName() {
        return name;
    }
    public People(int id,String name){
        this.id=id;
        this.name=name;
    }
    public boolean equals(Object obj){
        if(obj instanceof People){
            People p=(People)obj;
            return p.id==id&&p.name.equals(name);
        }
        if(this==obj){
            return true;
        }
        if(this==null)
            return false;
        return false;
    }
}
class Department{
    String DepartmentName;
    int DepartmentId;
    public Department(int DepartmentId,String DepartmentName){
        this.DepartmentId=DepartmentId;
        this.DepartmentName=DepartmentName;
    }
    public String getDepartmentName() {
        return DepartmentName;
    }
    public int getDepartmentId() {
        return DepartmentId;
    }
}
public class t5 {
    public static void main(String[] args) {
        HashMap<People,Department> map=new HashMap<People,Department>();
        People people1=new People(123,"jia");

        Department department1=new Department(11,"FinanceDepartment");
        map.put(people1,department1);
        People people2=new People(123,"jia");
        Department department2=new Department(12,"MarketingDepartment");blog

        map.put(people2,department2);
        People people3=null;
        System.out.println(people1.equals(people2));
        Iterator it=map.keySet().iterator();
        while(it.hasNext()){
            People tmp=(People)it.next();
            System.out.println(tmp.getName()+"  "+tmp.getId()+"  "+map.get            (tmp).getDepartmentName()
                    +"  "+map.get(tmp).getDepartmentId());
        }
    }
}

我將兩個People和Department做爲HashMap中的key和value的值,代碼中能夠看出來,people1和people2的內容是徹底相同的,那麼按照HashMap的性質,put數據進HashMap的時候當key值與map內的某一key值相同時,是將原來的value值覆蓋掉的。可是,運行的結果是

QQ截圖20160516191721

因而可知,key值徹底相同,可是並無把第一個的value值覆蓋掉。

先來看看HashMap中的put方法:

public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

能夠看到,在put中若是(其key的hashcod與map中key的hashcode相同,key值與map中key值相同(對於基礎數據類型),key值equal map中的key值(String或者封裝類型,引用類型))那麼將覆蓋其原有的value。

因此,緣由找到了,是由於people1和people2的hashcode不相同,致使沒有覆蓋。

在key,也就是value類中添加對hashcode的重寫。

public int hashCode() {
            int result = 17;
            result = 37 * result + name.hashCode();
            result = 37 * result + id;
            return result;
        }

或者簡單的能夠這樣寫:

public int hashCode(){
               return 50;
    }

添加完對hashcode的重寫以後,運行結果:

image

因此,通常對equals進行重寫的時候,也要把hashcode重寫!

 

2.hashMap跟hashTable的區別?

答:

HashTable和HashMap區別

①繼承不一樣。

public class Hashtable extends Dictionary implements Map public class HashMap extends AbstractMap implements Map

Hashtable 中的方法是同步的,而HashMap中的方法在缺省狀況下是非同步的。在多線程併發的環境下,能夠直接使用Hashtable,可是要使用HashMap的話就要本身增長同步處理了。

Hashtable中,key和value都不容許出現null值。

在HashMap中,null能夠做爲鍵,這樣的鍵只有一個;能夠有一個或多個鍵所對應的值爲null。當get()方法返回null值時,便可以表示 HashMap中沒有該鍵,也能夠表示該鍵所對應的值爲null。所以,在HashMap中不能由get()方法來判斷HashMap中是否存在某個鍵, 而應該用containsKey()方法來判斷。

④兩個遍歷方式的內部實現上不一樣。

Hashtable、HashMap都使用了 Iterator。而因爲歷史緣由,Hashtable還使用了Enumeration的方式 。

哈希值的使用不一樣,HashTable直接使用對象的hashCode。而HashMap從新計算hash值。

Hashtable和HashMap它們兩個內部實現方式的數組的初始大小和擴容的方式。HashTable中hash數組默認大小是11,增長的方式是 old*2+1。HashMap中hash數組的默認大小是16,並且必定是2的指數。 

相關文章
相關標籤/搜索