亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

java之map集合存放null值的問題

 更新時(shí)間:2023年11月01日 10:12:10   作者:馬丁半只瞄  
這篇文章主要介紹了java之map集合存放null值的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

java map集合存放null值問題

今天接到阿里的電話面試提到了一個(gè)問題是關(guān)于HashTable、HashMap的區(qū)別

集合類keyvaluesuper說明
HashTable不能為null不能為nullDictionary線程安全
ConcurrentHashMap不能為null不能為nullAbstractMap線程局部安全
TreeMap不能為null可以為nullAbstractMap線程不安全
HashMap可以為null可以為nullAbstractMap線程不安全

以此為記~

java 集合能否加入null值

項(xiàng)目場(chǎng)景

劍指 Offer 09. 用兩個(gè)棧實(shí)現(xiàn)隊(duì)列

	public int deleteHead() {
        while(s2.isEmpty()){
        //注意這里,我直接判斷第二個(gè)??站图尤氲谝粋€(gè)棧中的元素,沒有判斷第一個(gè)棧是否為空(當(dāng)時(shí)想的是第一個(gè)棧為空不會(huì)加入元素或者拋出異常)
            s2.offerFirst(s1.pollFirst());
        }
        if(s1.isEmpty()&&s2.isEmpty()){
            return -1;
        }
        return s2.pollFirst();
    }

問題描述

寫力扣題時(shí)出現(xiàn)了這個(gè)問題,原代碼在上面。

原因分析

嘗試輸出了下,發(fā)現(xiàn)總是返回空值,

1)認(rèn)為輸入棧(s1)為空會(huì)拋出異常,但是忘記了offer和poll針對(duì)異常不做處理,push和pop會(huì)拋出異常

2)跟著debug發(fā)現(xiàn)輸出棧(s2)元素永遠(yuǎn)不為空,因?yàn)榧尤肓藄1的null,這就有意思了,java中有的集合可以加入null,有的不可以,所以順便總結(jié)一下。

解決方案

	public int deleteHead() {
        while(s1.isEmpty()&&s2.isEmpty()){
            return -1;
        }
        if(s2.isEmpty()){
            while(!s1.isEmpty()){
                s2.offerFirst(s1.pollFirst());
            }
        }
        return s2.pollFirst();
    }

1.List

可以看到ArrayList可以存儲(chǔ)多個(gè)null,ArrayList底層是數(shù)組,添加null并未對(duì)他的數(shù)據(jù)結(jié)構(gòu)造成影響。LinkedList底層為雙向鏈表,node.value = null也沒有影響。

	@Test
    public void testArrayList() {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(null);
        list.add(null);
        System.out.println(list.size());//2
    }

    @Test
    public void testLinkedList() {
        LinkedList<Integer> list = new LinkedList<>();
        list.add(null);
        list.add(null);
        System.out.println(list.size());//2
    }

2.Set

Set底層是map,所以和map一樣

3.Map

關(guān)于Map,HashMap中最多只有一個(gè)key == null的節(jié)點(diǎn),因?yàn)閗ey相同時(shí),后面的節(jié)點(diǎn)會(huì)替換之前相同key的節(jié)點(diǎn),所以HashMap是可以添加key == null 的節(jié)點(diǎn)的,只不過只會(huì)存在一個(gè)put方法返回舊值。

TreeMap的put方法會(huì)調(diào)用compareTo方法,對(duì)象為null時(shí),會(huì)報(bào)空指針錯(cuò)。

	@Test
    public void testHashMap() {
        HashMap<Integer, Integer> map = new HashMap<>();
        map.put(null, null);
        map.put(null, null);
        System.out.println(map.size());//1
    }
    @Test
    public void testTreeMap() {
        TreeMap<Integer, Integer> map = new TreeMap<>();
        map.put(null, null);
        System.out.println(map.size());//NullPointerException
    }

TreeMap源碼

4.Vector

Vector 底層是數(shù)組,所以不會(huì)管你元素的內(nèi)容是什么,可以存儲(chǔ)多個(gè)null

    @Test
    public void VectorTest(){
        Vector box = new Vector();
        box.add(null);
        box.add(null);
        Assert.assertEquals(2,box.size()); //ok
    }

    /**
    *此為Vector的add函數(shù)
    **/
    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }

5.HashTable

HashTable底層為散列表,無論是key為null,還是value為null,都會(huì)報(bào)錯(cuò)

    @Test
    public void HashTableTest(){
        Hashtable table = new Hashtable();
        //table.put(new Object(),null); //Exception
        //table.put(null,new Object()); //Exception
        //table.put(null,null); //Exception
        Assert.assertEquals(1,table.size());
    }

    //此為hashTable#put函數(shù)源碼
   public synchronized V put(K key, V value) {
        // Make sure the value is not null
        if (value == null) {   //value 需要判空,所以value不可為null
            throw new NullPointerException();
        }

        // Makes sure the key is not already in the hashtable.
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();     //key需要擁有實(shí)例去調(diào)用hashCode方法,所以也不能為空
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> entry = (Entry<K,V>)tab[index];
        for(; entry != null ; entry = entry.next) {
            if ((entry.hash == hash) && entry.key.equals(key)) {
                V old = entry.value;
                entry.value = value;
                return old;
            }
        }

        addEntry(hash, key, value, index);
        return null;
    }

至于為什么hashtable鍵和值都設(shè)計(jì)成不能為null,??途W(wǎng)的一位大佬這樣說到:

6.ConcurrentHashMap

看上面那張圖

總結(jié)

結(jié)果:

  • List都可以添加null元素
  • HashMap可以有1個(gè)key為null的元素,TreeMap不能key為null的元素
  • Set底層是Map,所以HashSet可以有1個(gè)null的元素,TreeSet不能有key為null的元素。
  • -線程安全的類key和value都不能是null

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論