1.List

1.1 Arraylist 与 LinkedList 区别

  1. 是否保证线程安全: ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全
  2. 底层数据结构: Arraylist 底层使用的是 Object 数组;LinkedList 底层使用的是 双向链表 数据结构
  3. 插入和删除是否受元素位置的影响: ① ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。 比如:执行add(E e)方法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是O(1)。但是如果要在指定位置 i 插入和删除元素的话(add(int index, E element))时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。 ② LinkedList 采用链表存储,所以插入,删除元素时间复杂度不受元素位置的影响,都是近似O(1)而数组为近似O(n)。
  4. 是否支持快速随机访问: LinkedList 不支持高效的随机元素访问,而 ArrayList 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)方法)。
  5. 内存空间占用: ArrayList的空间浪费主要体现在在list列表的结尾会预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗比ArrayList更多的空间(因为要存放直接后继和直接前驱以及数据)。
  6. 注意:
  7. ArrayList遍历时使用普通for循环较快.
  8. LinkedList遍历时使用迭代器较快.

1.2 List中的迭代器

for(Object obj : list){
list.remove(obj)
}
注意:
一般list中迭代器不能使用此种方法移除元素,会触发 ConcurrentModifyException,如果要删除可以使用Iterator.remove()
此处如果切换成CopyOnWriteArrayList则可以正常删除

1.3 ArrayList的扩容机制

详见:

https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/collection/ArrayList-Grow.md

Map

2.1 Java1.8底层实现

底层=数组+链表(大小超过8,转换为红黑树)

HashMap 通过 key 的 hashCode 经过扰动函数处理过后得到 hash 值,然后通过 (n - 1) & hash 判断当前元素存放的位置(这里的 n 指的是数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突。

所谓扰动函数指的就是 HashMap 的 hash 方法。使用 hash 方法也就是扰动函数是为了防止一些实现比较差的 hashCode() 方法,换句话说使用扰动函数之后可以减少碰撞。

//hash方法
static final int hash(Object key) {
int h;
// key.hashCode():返回散列值也就是hashcode
// ^ :按位异或
// >>>:无符号右移,忽略符号位,空位都以0补齐
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); //扰动函数进行处理
}

2.2 HashMap长度为什么是2的幂次方

一般用hash对map的长度取模使用,当且仅当length是2的幂次方时,hash%length==hash&(length-1)成立,这样的话位与比取模%运算要更快

2.3 HashMap线程不安全问题

HashMap不是线程安全的类,两个线程同时去put可能引起数据不一致,在1.7以前还存在闭链问题,1.8以后解决了这个问题,并发环境下建议使用ConcurrentHashMap;

详情参见:

https://coolshell.cn/articles/9606.html

2.4 HashMap的其他资料

更详细的资料, 请参见:

https://zhuanlan.zhihu.com/p/21673805

2.5 ConcurrentHashMap的基本结构

1.底层数据结构:

JDK1.7的 ConcurrentHashMap 底层采用 分段的数组+链表 实现,JDK1.8 采用的数据结构跟HashMap1.8的结构一样,数组+链表/红黑二叉树。Hashtable 和 JDK1.8 之前的 HashMap 的底层数据结构类似都是采用 数组+链表 的形式,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的;

2.实现线程安全的方式:

① 在JDK1.7的时候,ConcurrentHashMap(分段锁) 对整个桶数组进行了分割分段(Segment),每一把锁只锁容器其中一部分数据,多线程访问容器里不同数据段的数据,就不会存在锁竞争,提高并发访问率。 到了 JDK1.8 的时候已经摒弃了Segment的概念,而是直接用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 synchronized 和 CAS 来操作。(JDK1.6以后 对 synchronized锁做了很多优化) 整个看起来就像是优化过且线程安全的 HashMap,虽然在JDK1.8中还能看到 Segment 的数据结构,但是已经简化了属性,只是为了兼容旧版本;synchronized只锁定当前链表或红黑二叉树的首节点,这样只要hash不冲突,就不会产生并发,效率又提升N倍。

Set

当你把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他加入的对象的hashcode值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,这时会调用equals()方法来检查hashcode相等的对象是否真的相同。如果两者相同,HashSet就不会让加入操作成功。

最后,感谢你读到了这里。

我最近又整合更新了一些资料,在这里分享给大家!

需要可以加我的架构群领取哦!!!(772300343)

最后,我是小架

我们下篇文章见!

Java中的集合类(List,Set.Map)的更多相关文章

  1. java中的集合类总结

    在使用Java的时候,我们都会遇到使用集合(Collection)的时候,但是Java API提供了多种集合的实现,我在使用和面试的时候频 频遇到这样的“抉择” . :)(主要还是面试的时候) 久而久 ...

  2. Java中的集合(十四) Map的实现类LinkedHashMap

    Java中的集合(十四) Map的实现类LinkedHashMap 一.LinkedHashMap的简介 LinkedHashMap是Map接口的实现类,继承了HashMap,它通过重写父类相关的方法 ...

  3. Java中的集合(十三) 实现Map接口的Hashtable

    Java中的集合(十三) 实现Map接口的Hashtable 一.Hashtable简介 和HashMap一样,Hashtable采用“拉链法”实现一个哈希表,它存储的内容是键值对(key-value ...

  4. Java中的集合(十一) 实现Map接口的TreeMap

    Java中的集合(十一) 实现Map接口的TreeMap 一.TreeMap简介(基于JDK1.8) TreeMap是基于红黑树数据结构,是一个key-value的有序集合,该映射根据其键的自然顺序进 ...

  5. JAVA中写时复制(Copy-On-Write)Map实现

    1,什么是写时复制(Copy-On-Write)容器? 写时复制是指:在并发访问的情景下,当需要修改JAVA中Containers的元素时,不直接修改该容器,而是先复制一份副本,在副本上进行修改.修改 ...

  6. Java中的集合(Set,List,Map)

    ******************collections类总结*************************** JAVA集合主要分为三种类型:    Set(集)    List(列表)    ...

  7. java中的集合类详情解析以及集合和数组的区别

    数组和链表 数组:所谓数组就是相同数据类型的元素按照一定顺序排列的集合. 它的存储区间是连续的,占用内存严重,所以空间复杂度很大,为o(n),但是数组的二分查找时间复杂度很小为o(1). 特点是大小固 ...

  8. 面试题: Java中各个集合类的扩容机制

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) Java 中提供了很多的集合类,包括,collection的子接口list.set,以及map等.由于它 ...

  9. java中 json和bean list map之间的互相转换总结

    JSON 与 对象 .集合 之间的转换 JSON字符串和java对象的互转[json-lib]   在开发过程中,经常需要和别的系统交换数据,数据交换的格式有XML.JSON等,JSON作为一个轻量级 ...

随机推荐

  1. Rust中的所有权,引用和借用

    这个有意思,指针解释获新生!!! fn main() { let mut s = String::from("hello"); s.push_str(", world!& ...

  2. 算法学习day01 栈和队列

    1,设计一个算法利用顺序栈的基本运算判断一个字符串是否是回文 解题思路:      由于回文是从前到后和从后到前读都是一样的,所以只要将待判断的字符串颠倒 然后与原字符串相比较,就可以决定是否是回文了 ...

  3. SQLAlchemy(1)

    介绍 SQLAlchemy是一个基于Python实现的ORM框架.该框架建立在 DB API之上,使用关系对象映射进行数据库操作,简言之便是:将类和对象转换成SQL,然后使用数据API执行SQL并获取 ...

  4. 201871010107-公海瑜《面向对象程序设计(java)》第十三周学习总结

    201871010107-公海瑜<面向对象程序设计(java)>第十三周学习总结            项目                      内容   这个作业属于哪个课程   ...

  5. 15-numpy笔记-莫烦pandas-3

    代码 import pandas as pd import numpy as np dates = pd.date_range('20130101', periods=6) df=pd.DataFra ...

  6. Eclipse中Git操作(七)

    1. Git插件 Eclipse在很早的版本就已内置了Git插件,所以我们不用再装. Preferences-->Team-->Git 2. 工程初始化为本地库 (1) 创建一个Maven ...

  7. USACO River Crossing

    洛谷 P2904 [USACO08MAR]跨河River Crossing https://www.luogu.org/problem/P2904 JDOJ 2574: USACO 2008 Mar ...

  8. API数据加密框架monkey-api-encrypt

    之前有写过一篇加密的文章<前后端API交互如何保证数据安全性>.主要是在Spring Boot中如何对接口的数据进行自动加解密操作,通过注解的方式来指定是否需要加解密. 原理也很简单,通过 ...

  9. 喜欢去知乎炸鱼?用python吧

    知乎高赞贴: 有一双大长腿是什么体验? 有一副迷人的身材是什么体验? 别用手机费劲的翻了,python帮你一臂之力 import re import requests import os import ...

  10. 利用SQL生成模型实体类

    DECLARE @TableName sysname = 'TableName'; DECLARE @Result VARCHAR(MAX) = 'public class ' + @TableNam ...