脚本之家

电脑版
提示:原网页已由神马搜索转码, 内容由www.jb51.net提供.
您的位置:首页软件编程java→ java map集合存放null值

java之map集合存放null值的问题

  更新时间:2023年11月01日 10:12:10  作者:马丁半只瞄 
这篇文章主要介绍了java之map集合存放null值的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

java map集合存放null值问题

今天接到阿里的电话面试提到了一个问题是关于HashTable、HashMap的区别

集合类
key
value
super
说明
HashTable
不能为null
不能为null
Dictionary
线程安全
ConcurrentHashMap
不能为null
不能为null
AbstractMap
线程局部安全
TreeMap
不能为null
可以为null
AbstractMap
线程不安全
HashMap
可以为null
可以为null
AbstractMap
线程不安全

以此为记~

java 集合能否加入null值

项目场景

剑指 Offer 09. 用两个栈实现队列

 public int deleteHead() {
while(s2.isEmpty()){
//注意这里,我直接判断第二个栈空就加入第一个栈中的元素,没有判断第一个栈是否为空(当时想的是第一个栈为空不会加入元素或者抛出异常)
s2.offerFirst(s1.pollFirst());
}
if(s1.isEmpty()&&s2.isEmpty()){
return -1;
}
return s2.pollFirst();
}

问题描述

写力扣题时出现了这个问题,原代码在上面。

原因分析

尝试输出了下,发现总是返回空值,

1)认为输入栈(s1)为空会抛出异常,但是忘记了offer和poll针对异常不做处理,push和pop会抛出异常

2)跟着debug发现输出栈(s2)元素永远不为空,因为加入了s1的null,这就有意思了,java中有的集合可以加入null,有的不可以,所以顺便总结一下。

解决方案

 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可以存储多个null,ArrayList底层是数组,添加null并未对他的数据结构造成影响。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

关于Map,HashMap中最多只有一个key == null的节点,因为key相同时,后面的节点会替换之前相同key的节点,所以HashMap是可以添加key == null 的节点的,只不过只会存在一个put方法返回旧值。

TreeMap的put方法会调用compareTo方法,对象为null时,会报空指针错。

 @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 底层是数组,所以不会管你元素的内容是什么,可以存储多个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;
}

5.HashTable

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<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键和值都设计成不能为null,牛客网的一位大佬这样说到:

6.ConcurrentHashMap

看上面那张图

总结

结果:

  • List都可以添加null元素
  • HashMap可以有1个key为null的元素,TreeMap不能key为null的元素
  • Set底层是Map,所以HashSet可以有1个null的元素,TreeSet不能有key为null的元素。
  • -线程安全的类key和value都不能是null

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

    • 这篇文章主要介绍了Spring Security常用过滤器实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
      2020-03-03
    • 在日常编码过程中常常涉及到事务,在前两天看到一篇文章提到了Spring事务,那么在此总结下在Spring环境下事务失效的几种原因
      2021-09-09
    • 这篇文章主要介绍了SpringMVC中的DispatcherServlet详细解析,DispatcherServlet也是一个Servlet,它也能通过Servlet的API来响应请求,从而成为一个前端控制器,Web容器会调用Servlet的doGet()以及doPost()等方法,需要的朋友可以参考下
      2023-12-12
    • 这篇文章主要介绍了Spring事务失效问题分析及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
      2020-01-01
    • Java经验点滴:处理没有被捕获的异常...
      2006-12-12
    • 本文主要介绍了MybatisPlus如何完成字段类型转换,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
      2023-03-03
    • 这篇文章主要介绍了java Lombok之@Accessors用法及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
      2023-03-03
    • 本系统采用Java,MySQL 作为系统数据库,重点开发并实现了系统各个核心功能模块,包括采编模块、典藏模块、基础信息模块、流通模块、期刊模块、查询模块、评论模块、系统统计模块以及帮助功能模块
      2021-06-06
    • Spring MVC中的参数绑定还是蛮重要的,最近在使用中遇到了同名参数绑定的问题,想着总结分享出来,下面这篇文章主要给大家介绍了关于Spring MVC同名参数绑定问题的解决方法,需要的朋友可以参考借鉴,下面来一起看看吧。
      2017-08-08
    • 这篇文章主要介绍了Struts 2 数据校验功能及校验问题的解决方案的相关资料,需要的朋友可以参考下
      2016-09-09

    最新评论