Java集合相关
Java集合相关内容
一、Collection集合
-
List
- ArrayList:非线程安全,在扩容时每次增加50%。动态数组的数据结构。
- Vector:线程安全,底层使用的是数组方式存数据。效率低,Vector 扩容每次会增加 1 倍。该类下的所有方法都是同步的
- LinkedList:线程不安全。底层用的数组存数据。是双向链表的数据结构,是线性的数据存储方式,要移动指针从前往后依次查找。他的节点除了要存数据,还存储了两个引用,一个指向前一个元素,一个是指向后一个元素。
-
Set
- HashSet(无序,唯一):是基于HashMap实现的,基本上都是直接调用底层 HashMap 的相关方法来完成。HashSet 中的add ()方法向Set中添加元素。仅存储对象,HashSet较HashMap来说比较慢,因为HashMap是使用的唯一键获取对象。
- LinkedHashSet:LinkedHashSet 继承与 HashSet,并且其内部是通过 LinkedHashMap 来实现的。有点类似于我们之前说的LinkedHashMap 其内部是基于 Hashmap 实现一样,不过还是有一点点区别的。
- TreeSet(有序,唯一):红黑树(自平衡的排序二叉树。)
-
Map
-
HashMap:线程不安全,允许空键空值,是数组和链表结合体的数据表结构。他是基于Hash算法实现的。在jdk1.8后,当链表中的节点数据超过8个后改链表会转为红黑树来提高查询效率。每次扩展的时候都是扩展2倍。
JDK1.8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突).JDK1.8以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间
-
HashTable:线程安全,数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的
-
LinkedHashMap:继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。
-
TreeMap:红黑树(自平衡的排序二叉树)
-
二、List和Set的区别
-
都是继承Conllection接口。
-
List特点:一个有序容器,元素可以重复,可以插入多个null元素,元素都有索引,常用的实现类:ArrayList、Vector、LinkedList
-
Set特点:一个无序容器,不可以存储重复元素,只允许存入一个null元素,必须保证元素唯一性。Set接口实现类:HashSet、LinkedHashSet、TreeSet
-
List支持for循环,可以通过下表遍历,也可以用迭代器,但set只能用迭代,因为他无序。
-
set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
-
List:和数组类似,List可以动态的增长,查效率高,增加删除效率低,因为他会引起其他元素的改变。
三、ArrayList集合
ArrayList的优点如下:
- ArrayList 底层以数组实现,是一种随机访问模式。ArrayList 实现了 RandomAccess 接口,因此查找的时候非常快。
- ArrayList 在顺序添加一个元素的时候非常方便。
ArrayList 的缺点如下:
- 删除元素的时候,需要做一次元素复制操作。如果要复制的元素很多,那么就会比较耗费性能。
- 插入元素的时候,也需要做一次元素复制操作,缺点同上。
ArrayList 比较适合顺序添加、随机访问的场景。
四、数组和 List 之间的转换
- 数组转 List:使用 Arrays. asList(array) 进行转换。
- List 转数组:使用 List 自带的 toArray() 方法。
五、HashMap在JDK1.7和JDK1.8中有哪些不同?HashMap的底层实现
在Java中,保存数据有两种比较简单的数据结构:数组和链表。数组的特点是:寻址容易,插入和删除困难;链表的特点是:寻址困难,但插入和删除容易;所以我们将数组和链表结合在一起,发挥两者各自的优势,使用一种叫做拉链法的方式可以解决哈希冲突。
六、什么是哈希
简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
七、什么是哈希冲突
当两个不同的输入值,根据同一散列函数计算出相同的散列值的现象,我们就把它叫做碰撞(哈希碰撞)
八、怎么解决哈希冲突
- 使用链地址法(使用散列表)来链接拥有相同hash值的数据;
- 使用2次扰动函数(hash函数)来降低哈希冲突的概率,使得数据分布更平均。
- 引入红黑树进一步降低遍历的时间复杂度,使得遍历更快。
九、HashMap 与 HashTable 有什么区别?
- 线程安全: HashMap 是非线程安全的,HashTable 是线程安全的;HashTable 内部的方法基本都经过 synchronized 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap 吧!);
- 效率: 因为线程安全的问题,HashMap 要比 HashTable 效率高一点。另外,HashTable 基本被淘汰,不要在代码中使用它;
- 对Null key 和Null value的支持: HashMap 中,null 可以作为键,这样的键只有一个,可以有一个或多个键所对应的值为 null。但是在 HashTable 中 put 进的键值只要有一个 null,直接抛NullPointerException。
- **初始容量大小和每次扩充容量大小的不同 **: ①创建时如果不指定容量初始值,Hashtable 默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap 默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。②创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为2的幂次方大小。也就是说 HashMap 总是使用2的幂作为哈希表的大小,后面会介绍到为什么是2的幂次方。
- 底层数据结构: JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。
- 推荐使用:在 Hashtable 的类注释可以看到,Hashtable 是保留类不建议使用,推荐在单线程环境下使用 HashMap 替代,如果需要多线程使用则用 ConcurrentHashMap 替代。

浙公网安备 33010602011771号