国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

HashMap,HashSet,Hashtable,Vector,ArrayList 的關(guān)系

microcosm1994 / 3026人閱讀

摘要:繼承的類,泛型為時(shí),注意和其他的類型不同。因?yàn)槭蔷€程安全簡(jiǎn)單來(lái)說(shuō),是個(gè)一維數(shù)組。同樣,指定和,如果中間發(fā)生變化則會(huì)拋出異常。最后,可以,然后,使用基類可以實(shí)現(xiàn)和的快速賦值。線程安全也是線程安全的,和一樣,連函數(shù)都喪心病狂地同步了。

這么幾個(gè)比較常用的但是比較容易混淆的概念同出于 java.util 包。本文僅作幾個(gè)類的淺度解析。
(本文基于JDK1.7,源碼來(lái)自openjdk1.7。)

├── Collection
│?? ├── List
│   │?? ├── ArrayList
│?? │   ├── Vector
│?? │   └── LinkedList and so on;
│   Set
│?? ├── HashSet
│?? └── LinkedHashSet and so on;
└── Map
 ?? ├── Hashtable
 ?? ├── HashMap
 ?? └── WeakHashMap and so on;

Collection和Map

按理來(lái)說(shuō)和這兩者沒(méi)有什么特別關(guān)系。然而本文中仍然將這兩個(gè)混在一起:

第一,HashSet,HashMap,Hashtable長(zhǎng)得太像了,沒(méi)有理由不寫(xiě)再一起。

第二,HashSet是個(gè)Set,其實(shí)骨子里是個(gè)Map。

List

繼承List的類,泛型為Integer時(shí),注意和其他的類型不同。(因?yàn)镮ndex是Integer)

線程安全

簡(jiǎn)單來(lái)說(shuō),List是個(gè)一維數(shù)組。Vector和ArrayList區(qū)別在于:

Vector是個(gè)線程安全的,而ArrayList不是。這點(diǎn)看源碼可以看出來(lái),Vector中各種synchronized,甚至連size屬性都喪心病狂地synchronized了。

同樣,Iterator指定Vector和ArrayList,如果中間發(fā)生變化則會(huì)拋出ConcurrentModificationException異常。
不僅僅是List,很多地方的Iterator都有這個(gè)異常,

自增大小

ArrayList沒(méi)辦法設(shè)置自增大小,但是仍然可以自增。
Vector可以設(shè)置自增大小。

ArrayList的自增函數(shù):

Vector的自增函數(shù):

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                     capacityIncrement : oldCapacity);
    //在這里,如果沒(méi)有設(shè)置自增大小的話,那么默認(rèn)自增大小則是原來(lái)的Vector大小。
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}

ArrayList自增函數(shù):

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    //新長(zhǎng)度則是舊長(zhǎng)度的大小加上一個(gè)移位運(yùn)算(一半的大?。?。
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

所以可以簡(jiǎn)單的認(rèn)為Vector默認(rèn)自增一倍的長(zhǎng)度,ArrayList則是默認(rèn)自增一半的長(zhǎng)度。

同樣,對(duì)他們的源碼分析:
Vector可以設(shè)置自增大小,而ArrayList則無(wú)法設(shè)置(沒(méi)有這個(gè)構(gòu)造方法)。

public Vector(int initialCapacity, int capacityIncrement) 

最后,可以 List list=new ArrayList<>();,然后list=new Vector<>();,使用基類List可以實(shí)現(xiàn)ArrayList和Vector的快速賦值。

Map

Map可以當(dāng)成是簡(jiǎn)單的“Key-Value”數(shù)據(jù)庫(kù),例如memcached和redis。

  

Hashtable基于Directory,有種說(shuō)法是Directory已經(jīng)過(guò)時(shí),所以更推薦使用Map。

線程安全

Hashtable也是線程安全的,和Vector一樣,連size函數(shù)都喪心病狂地同步了。

public synchronized int size() {                                                                                                             
    return count;
}       

HashMap不是線程安全的,當(dāng)然也可以用其他的黑科技實(shí)現(xiàn)同步,例如SynchronizedMap和ConcurrentHashMap。
那個(gè)以后再說(shuō)……

空值

HashMap允許在Key和Value中都出現(xiàn)null值。例如:

v.toString()
{null=null, 1=66, 2=null, 3=4d, 4=0f, 5=null}

而Hashtable則不允許K/V的任何一個(gè)出現(xiàn)null值,但是允許空字符串。

Hashtable v=new Hashtable();
v.put("3s",null); 

直接報(bào)錯(cuò):java.lang.NullPointerException。
這個(gè)和內(nèi)部實(shí)現(xiàn)有關(guān),Hashtable需要用到hashCode,所以必須要確保K/V不為null。

相關(guān)代碼寫(xiě)死在源碼里:

public synchronized V put(K key, V value) {
 // Make sure the value is not null
 if (value == null) {
     throw new NullPointerException();
 }
 //下面對(duì)hashCode做點(diǎn)事情。
Set

HashSet本質(zhì)上是一個(gè)Collection,類似于List,是列表/集合,不是K-V的Map,但是它骨子里是一個(gè)HashMap……

這么說(shuō)可能會(huì)更易于理解:
HashSet對(duì)外是“類”的集合,實(shí)際上是內(nèi)部維護(hù)了一個(gè)HashMap進(jìn)行實(shí)現(xiàn)。

實(shí)際上存儲(chǔ)的是兩個(gè):hashCode和類本身(字符串/自定義類等)。

HashSet進(jìn)行add的時(shí)候,會(huì)先進(jìn)行驗(yàn)證hashCode:
(HashSet進(jìn)行add操作實(shí)際上是對(duì)Map的put操作)

public V put(K key, V value) {
    if (table == EMPTY_TABLE) {
        inflateTable(threshold);
    }
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key);//本函數(shù)里有hashCode
    int i = indexFor(hash, table.length);
    for (Entry 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;
}
一個(gè)對(duì)HashSet的自定義類的操作:
 class Name  
{  
    private String first;   
    private String last;   

    public Name(String first, String last)   
    {   
        this.first = first;   
        this.last = last;   
    }   

    public boolean equals(Object o)   
    {   
        if (this == o)   
        {   
            return true;   
        }   

    if (o.getClass() == Name.class)   
        {   
            Name n = (Name)o;   
            return n.first.equals(first)   
                && n.last.equals(last);   
        }   
        return false;   
    }   
}  

public class HashSetTest  
{  
    public static void main(String[] args)  
    {   
        Set s = new HashSet();  
        s.add(new Name("abc", "123"));  
        System.out.println(  
            s.contains(new Name("abc", "123")));  
    }  
}   

代碼來(lái)自java中HashSet詳解

  

粗看上去是會(huì)返回true的,實(shí)際返回false。因?yàn)?HashSet 判斷兩個(gè)對(duì)象相等的標(biāo)準(zhǔn)除了要求通過(guò) equals() 方法比較返回 true 之外,還要求兩個(gè)對(duì)象的 hashCode() 返回值相等。而上面程序沒(méi)有重寫(xiě) Name 類的 hashCode() 方法,兩個(gè) Name 對(duì)象的 hashCode() 返回值并不相同,因此 HashSet 會(huì)把它們當(dāng)成 2 個(gè)對(duì)象處理,因此程序返回 false。如果想返回true,需要重寫(xiě)equals方法和hashCode方法。

  

至于hashCode,就是另一篇文章才解釋得清的了。

集合操作

Set其實(shí)做集合操作更加簡(jiǎn)單。例如:

import java.util.*;
public class SetOperation {
       public static void main(String[] args) {
            Set result = new HashSet();
            Set set1 = new HashSet(){{
                add(1);
                add(3);
                add(5);
            }};

            Set set2 = new HashSet(){{
                add(1);
                add(2);
                add(3);
            }};

            result.clear();
            result.addAll(set1);
            result.retainAll(set2);
            System.out.println("交集:"+result);

            result.clear();
            result.addAll(set1);
            result.removeAll(set2);
            System.out.println("差集:"+result);

            result.clear();
            result.addAll(set1);
            result.addAll(set2);
            System.out.println("并集:"+result);

        }
}

輸出:

交集:[1, 3]
差集:[5]
并集:[1, 2, 3, 5]
參考文檔

hashSet中的equals方法和hashCode方法

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/64382.html

相關(guān)文章

  • Java集合總結(jié)

    摘要:概述集合類主要有大分支,及。不能保證元素的排列順序,順序有可能發(fā)生變化不是同步的集合元素可以是但只能放入一個(gè)是接口的唯一實(shí)現(xiàn)類,可以確保集合元素處于排序狀態(tài)。如果這兩個(gè)的通過(guò)比較返回,新添加的將覆蓋集合中原有的,但不會(huì)覆蓋。 概述 Java集合類主要有2大分支,Collection及Map。Collection體系如下: https://upload-images.jianshu......

    toddmark 評(píng)論0 收藏0
  • 這幾道Java集合框架面試題在面試中幾乎必問(wèn)

    摘要:若遇到哈希沖突,則將沖突的值加到鏈表中即可。之后相比于之前的版本,之后在解決哈希沖突時(shí)有了較大的變化,當(dāng)鏈表長(zhǎng)度大于閾值默認(rèn)為時(shí),將鏈表轉(zhuǎn)化為紅黑樹(shù),以減少搜索時(shí)間。有序,唯一紅黑樹(shù)自平衡的排序二叉樹(shù)。 本文是最最最常見(jiàn)Java面試題總結(jié)系列第三周的文章。主要內(nèi)容: Arraylist 與 LinkedList 異同 ArrayList 與 Vector 區(qū)別 HashMap的底層...

    bigdevil_s 評(píng)論0 收藏0
  • 關(guān)于java集合框架總結(jié)

    摘要:是哈希表實(shí)現(xiàn)的,中的數(shù)據(jù)是無(wú)序的,可以放入,但只能放入一個(gè),兩者中的值都不能重復(fù),就如數(shù)據(jù)庫(kù)中唯一約束。四和的相同點(diǎn)和區(qū)別相同兩者都是基于哈希表實(shí)現(xiàn)的內(nèi)部也都是通過(guò)單鏈表解決沖突問(wèn)題同樣實(shí)現(xiàn)了序列化和克隆接口區(qū)別繼承的父類不同。 一.Arraylist與LinkedList有什么區(qū)別? 1、ArrayList是實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),因?yàn)榈刂愤B續(xù),一旦數(shù)據(jù)存儲(chǔ)好了,查詢操作效率...

    Coding01 評(píng)論0 收藏0
  • 集合小記

    摘要:解決沖突開(kāi)放定址法拉鏈法表解決沖突開(kāi)放定址法再哈希法鏈地址法建立公共溢出區(qū)并發(fā)包中的線程安全的集合容器線程安全的,不允許為,默認(rèn)個(gè)的數(shù)組,每個(gè)中實(shí)現(xiàn)就是了,通過(guò)定位。基于數(shù)組,線程安全的集合類,容量可以限制。 List   List?元素是有序的、可重復(fù),實(shí)現(xiàn)List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。   ArrayList:動(dòng)態(tài)數(shù)組...

    alaege 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

microcosm1994

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<