栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java集合中是否可以添加null值(或者key为null)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java集合中是否可以添加null值(或者key为null)

文章目录

前言1. HashTable2. HashMap3. HashSet4. Vector5. ArrayList6. linkedList7. linkedHashMap8. ConcurrentHashMap9. ConcurrentSkipListSet10. ConcurrentlinkedDeque和ConcurrentlinkedQueue11. CopyOnWriteArrayList和CopyOnWriteArraySet12. linkedBlockingDeque、linkedBlockingQueue、ArrayBlockingQueue、PriorityBlockingQueue总结

前言

面试、考试经常问的一个问题:xx集合是否可以添加null值?看到这个问题,总是拿不准,本篇就来总结下,常用数据集合是否可以添加null值(或key为null)。

1. HashTable

HashTable不允许null作为key或者value,如果任意一个为null的话,会抛出NullPointerException.

    public synchronized V put(K key, V value) {
        // Make sure the value is not null
        if (value == null) {
            throw new NullPointerException();
        }

        // Makes sure the key is not already in the hashtable.
        Entry tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry entry = (Entry)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的源码,如果value为空,会在参数检查时抛出空指针异常;如果key为空,则在调用key.hashCode()的时候发生空指针异常。

2. HashMap

HashMap允许key或者value为null,当key为null时,null可以作为正常的key,可以通过hashMap.get(null)来获取值;null也可以作为value添加,均可以正常使用。

@Test
public void addNullTest() {
    Map hashMap = new HashMap<>();
    hashMap.put(null, null);
    hashMap.put(null, "Hello");
    hashMap.put("Hello", null);
    System.out.println(hashMap.get(null));
    System.out.println(hashMap.get("Hello"));
}

上述的代码输出结果为:

Hello
null
3. HashSet

HashSet内部使用了HashMap实现,所以HashSet可以添加null值。验证代码如下:

@Test
public void addNullTest() {
    Set hashSet = new HashSet<>();
    hashSet.add(null);
    hashSet.add(null);
    System.out.println(hashSet.contains(null));
}

输出结果为:

true
4. Vector

Vector内部维护了一个数组,是可以添加null作为值的,验证代码如下:

@Test
public void addNullTest() {
    Vector vector = new Vector<>();
    vector.add(null);
    vector.add(null);
    vector.add(null);
    System.out.println(vector.contains(null));
}

输出结果为:

3
true
5. ArrayList

ArrayList可以添加null为值,验证代码如下:

@Test
public void addNullTest() {
    List arrayList = new ArrayList<>();
    arrayList.add(null);
    arrayList.add(null);
    arrayList.add(null);
    System.out.println(arrayList.size());
    System.out.println(arrayList.contains(null));
}

输出结果为;

3
true
6. linkedList

linkedList允许添加null作为值,验证代码和ArrayList形式一致,不贴验证代码了。

7. linkedHashMap

linkedHashMap允许key或者value为null,或者两者同时为null,当key为null的时候,其hashCode为0,也可以正常当作key值。下面是验证代码:

@Test
public void addNullTest() {
    linkedHashMap linkedHashMap = new linkedHashMap<>();
    linkedHashMap.put(null, null);
    linkedHashMap.put(null, "Hello");
    linkedHashMap.put("Hello", null);
    System.out.println(linkedHashMap.get(null));
    System.out.println(linkedHashMap.get("Hello"));
}

输出结果为:

Hello
null
8. ConcurrentHashMap

ConcurrentHashMap不允许key或者value为null,会在运行时抛出NullPointerException。以下截取的ConcurrentHashMap的部分源码:

public V put(K key, V value) {
    return putVal(key, value, false);
}

final V putVal(K key, V value, boolean onlyIfAbsent) {
    if (key == null || value == null) throw new NullPointerException();
    // code fragment...
}

可以看到,putVal里面的参数检查,如果任意一项为空,则会抛出空指针异常。

9. ConcurrentSkipListSet

ConcurrentSkipListSet不允许添加null作为值,原因和ConcurrentHashMap类似,添加元素时会对参数进行检查,如果为null会抛出空指针异常。

10. ConcurrentlinkedDeque和ConcurrentlinkedQueue

两者都不允许添加null值,因为在添加值时都会检查添加进来的值是否为null,如果为null会抛出NullPointerException.

11. CopyOnWriteArrayList和CopyonWriteArraySet

这两种数据结构均允许null值的添加。验证代码:

@Test
public void addNullTest() {
    CopyOnWriteArrayList copyonWriteArrayList = new CopyOnWriteArrayList<>();
    copyOnWriteArrayList.add(null);
    copyOnWriteArrayList.add(null);
    System.out.println(copyOnWriteArrayList.size());
    System.out.println(copyOnWriteArrayList.contains(null));
    CopyOnWriteArraySet copyonWriteArraySet = new CopyOnWriteArraySet<>();
    copyOnWriteArraySet.add(null);
    copyOnWriteArraySet.add(null);
    System.out.println(copyOnWriteArraySet.size());
    System.out.println(copyOnWriteArraySet.contains(null));
}

输出结果为:

2
true
1
true
12. linkedBlockingDeque、linkedBlockingQueue、ArrayBlockingQueue、PriorityBlockingQueue

这几个都不支持null作为值,入参有参数检查,null会抛出NullPointerException。

总结

支持添加null的集合有:

HashMapHashSetVectorArrayListlinkedListlinkedHashMapCopyOnWriteArrayListCopyOnWriteArraySet

不支持添加null的集合有:

HashTableConcurrentHashMapConcurrentSkipListSetConcurrentlinkedDequeConcurrentlinkedQequelinkedBlockingDequelinkedBlockingQueueArrayBlockingQueuePriorityBlockingQueue

可能还有些许遗漏,欢迎大家在评论区补充。遇到这种问题,通过尝试或者查看源码就可以确定。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/770449.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号