List、Map、Set三个接口存取元素时,各有什么特点

List接口以特定索引来存取元素,可以有重复元素

Set接口不可以存放重复元素(使用equals方法区分是否重复)

Map接口保存的是键值对(key-value-pair)映射,映射关系可以是一对一或者多对一(key唯一)

Set和Map容器都有基于哈希存储和排序树的两种实现版本。基于哈希存储的版本的实现理论存取时间复杂度是O(1),而基于排序树版本的的实现在插入或者删除元素时会按照元素或者元素的key构成排序树从而达到去重和排序的效果

哈希存储的版本的实现理论存取时间复杂度是O(1)

HashMap源码:

put方法

1 1 public V put(K key, V value) { 2 2 // HashMap允许存放null键和null值。 3 3 // 当key为null时,调用putForNullKey方法,将value放置在数组第一个位置。 4 4 if (key == null) 5 5 return putForNullKey(value); 6 6 // 根据key的keyCode重新计算hash值。 7 7 int hash = hash(key.hashCode()); 8 8 // 搜索指定hash值在对应table中的索引。 9 9 int i = indexFor(hash, table.length); 1010 // 如果 i 索引处的 Entry 不为 null,通过循环不断遍历 e 元素的下一个元素。 1111 for (Entry<K,V> e = table[i]; e != null; e = e.next) { 1212 Object k; 1313 if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 1414 V oldValue = e.value; 1515 e.value = value; 1616 e.recordAccess(this); 1717 return oldValue; 1818 } 1919 } 2020 // 如果i索引处的Entry为null,表明此处还没有Entry。 2121 modCount++; 2222 // 将key、value添加到i索引处。 2323 addEntry(hash, key, value, i); 2424 return null; 2525 }

get方法

1 1 public V get(Object key) { 2 2 if (key == null) 3 3 return getForNullKey(); 4 4 int hash = hash(key.hashCode()); 5 5 for (Entry<K,V> e = table[indexFor(hash, table.length)]; 6 6 e != null; 7 7 e = e.next) { 8 8 Object k; 9 9 if (e.hash == hash && ((k = e.key) == key || key.equals(k))) 1010 return e.value; 1111 } 1212 return null; 1313 }

该过程一共分四步:

  1. 根据key的keyCode重新计算hash值
  2. 搜索指定hash值在对应table中的索引
  3. 遍历键值对的链表,根据key找到对应的键值对
  4. 从键值对中获取value值

  这四步中,1/2/4每一步的时间复杂度都是O(1),但是第3步是for循环,时间复杂度是O(n),想要保证存取时间复杂度是O(1),那么只有键值对链表长度是1,也就是只有那个hash算法尽量减少冲突,才能使链表长度尽可能短,理想状态为1所以HashMap的查找时间复杂度只有在最理想的情况下才会为O(1)

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java中map接口hashMap以及Enty之间的用法和关系

java中map接口hashMap以及Enty之间的转换首先说的是map接口:Map提供了一种映射关系,其中的元素是以键值对(keyvalue)的形式存储的,能够实现根据key快速查找value;建(key值)不可重复,value值可以重复,一个value值可以和很多key值形成对应关系,每个建最多只能映射到一个值。Ma

Java集合面试题

CollectionSet和hashCode以及equals方法的联系Set内存放的元素为什么不可以重复,内部是如何保证和实现的?List和Set区别List和Map区别Arraylist与LinkedList区别ArrayList与Vector区别Arraylist与LinkedList默认空间是