php的map可以为null吗,关于List,Set,Map能否存储null

本文源码为jdk1.8版本

喵的,今天面试问这个卡壳了,明明我之前看了的,邀请面试的是你,拒绝我的也是你,你为什么那么熟练啊QAQ

@Test

public void testArrayList(){

ArrayList list = new ArrayList<>();

list.add(null);

list.add(null);

Assert.assertEquals(2,list.size()); // success

}

@Test

public void testLinkedList(){

LinkedList list = new LinkedList<>();

list.add(null);

list.add(null);

Assert.assertEquals(2,list.size()); // success

}

首先是List,可以看到ArrayList可以存储多个null,ArrayList底层是数组,添加null并未对他的数据结构造成影响。LinkedList底层为双向链表,node.value = null也没有影响。

@Test

public void testHashMap(){

HashMap map = new HashMap<>();

map.put(null,null);

Assert.assertEquals(1,map.size()); //OK size = 1

map.put(null,null);

Assert.assertEquals(2,map.size()); //Error size = 1

}

@Test

public void testTreeMap(){

TreeMap map = new TreeMap<>();

map.put(null,null);

Assert.assertEquals(1,map.size()); //Error NullPointException

}

关于Map,HashMap中最多只有一个key == null的节点,因为key相同时,后面的节点会替换之前相同key的节点,所以HashMap是可以添加key == null 的节点的,只不过只会存在一个,有兴趣的话可以去看源码(tips:源码真的眼花缭乱,可以尝试自己写上注释,更容易看懂,菜鸟的方法)put方法返回旧值。TreeMap的put方法会调用compareTo方法,对象为null时,会报空指针错。

@Test

public void testHashSet(){

HashSet set = new HashSet<>();

set.add(null);

Assert.assertEquals(1,set.size()); //OK size = 1

set.add(null);

Assert.assertEquals(2,set.size()); //Error size = 1

}

@Test

public void testTreeSet(){

TreeSet set = new TreeSet<>();

set.add(null); //Error NullPointException

}

最后是Set,HashSet底层是HashMap,所以它的put()如下,也只能有一个null。

private static final Object PRESENT = new Object();

public boolean add(E e) {

return map.put(e, PRESENT)==null;

}

TreeSet的put()也是如此。

public boolean add(E e) {

return m.put(e, PRESENT)==null;

}

结果:

List都可以添加null元素

HashMap可以有1个key为null的元素,TreeMap不能有key为null的元素

Set底层是Map

所以HashSet可以有1个null的元素,TreeSet不能有key为null的元素。

面试官,您看您还要我吗?

续上:

Vector 底层是数组,所以不会管你元素的内容是什么,可以存储多个null

@Test

public void VectorTest(){

Vector box = new Vector();

box.add(null);

box.add(null);

Assert.assertEquals(2,box.size()); //ok

}

/**

*此为Vector的add函数

**/

public synchronized boolean add(E e) {

modCount++;

ensureCapacityHelper(elementCount + 1);

elementData[elementCount++] = e;

return true;

}

HashTable底层为散列表,无论是key为null,还是value为null,都会报错

@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函数源码

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需要拥有实例去调用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键和值都设计成不能为null,牛客网的一位大佬这样说到:

c32e192e371d

以上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
unordered_set和unordered_map是C++标准库中的关联式容器,它们的特点是元素的存储是无序的。也就是说,unordered_set和unordered_map不会按照元素的插入顺序或者键的大小进行排序。因此,unordered_set和unordered_map无法直接实现排序功能。 如果你需要对元素进行排序,你可以考虑使用其他容器,例如std::set和std::map。这些容器会根据元素的特性进行排序。如果你需要自定义排序规则,你可以使用比较函数或者函数对象来指定排序的方式。 另外,如果你需要对unordered_set或unordered_map中的元素进行排序,并且你不需要保持元素的唯一性,你可以将元素拷贝到一个std::vector中,然后使用std::sort函数对vector进行排序。这样可以实现对元素的排序功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [unordered_set和unordered_map用法详解](https://blog.csdn.net/weixin_43679037/article/details/118833261)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [C++ unordered_map和unordered_set的使用](https://blog.csdn.net/qq_61635026/article/details/126857258)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值