java数据结构

String,StringBuilder,StringBuffer:

                   String                        StringBuffer                              StringBuilder
执行速度        最差                        其次                                                    最高
线程安全      线程安全                       线程安全              线程不安全(没使用线程同步操作)
使用场景    少量字符串操作    多线程环境下的大量操作    单线程环境下的大量操作

String:
对于String来说,是把数据存放在了常量池中,因为所有的String,默认都是以常量形式保存,且由final修饰,因此在线程池中它是线程安全的。因为每一个String当被创建好了以后,他就不再发生任何变化,但是它的执行速度是最差的。我们要创建String的时候,他在常量池中对这些信息进行处理,如果在程序中出现了大量字符串拼接的工作,效率是非常底下的。因此使用场景是在少量字符串操作的时候才建议直接使用String来操作。

StirngBuffer:(效率不如StringBuilder,但远比String要高):
StringBuffer相对于StringBuilder效率要相对低一点,但也远比String要高的多。效率低的原因:对于StringBuffer来说更多的考虑到了多线程的情况,在进行字符串操作的时候,它使用了synchronize关键字,对方法进行了同步处理。
因此StringBuffer适用于多线程环境下的大量操作。

StringBuilder:(没有考虑线程安全问题):
线程安全与线程不安全:
在进行多线程处理的时候,如果多个线程对于这一个对象同时产生操作,会产生预期之外的结果。对于StringBuilder来说,执行效率虽然高,但是因为线程不安全,所以不建议在多线程的环境下对同一个StringBuilder对象进行操作。
因此StringBuilder适用于单线程环境下的大量字符串操作。

java集合:

List:

ArrayListObject[] 数组。

VectorObject[] 数组。

LinkedList:双向链表(JDK1.6 之前为循环链表,JDK1.7 取消了循环)

Arraylist扩容机制:

第一种情况,当ArrayList的容量为0时,此时添加元素的话,需要扩容,三种构造方法创建的ArrayList在扩容时略有不同:

1.无参构造,创建ArrayList后容量为0,添加第一个元素后,容量变为10,此后若需要扩容,则正常扩容。

2.传容量构造,当参数为0时,创建ArrayList后容量为0,添加第一个元素后,容量为1,此时ArrayList是满的,下次添加元素时需正常扩容。

3.传列表构造,当列表为空时,创建ArrayList后容量为0,添加第一个元素后,容量为1,此时ArrayList是满的,下次添加元素时需正常扩容。

第二种情况,当ArrayList的容量大于0,并且ArrayList是满的时,此时添加元素的话,进行正常扩容,每次扩容到原来的1.5倍。

Set:

HashSet(无序,唯一): 基于 HashMap 实现的,底层采用 HashMap 来保存元素。

LinkedHashSet: LinkedHashSetHashSet 的子类,并且其内部是通过 LinkedHashMap 来实现的。

TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树)。

比较 HashSet、LinkedHashSet 和 TreeSet 三者的异同

1. HashSetLinkedHashSetTreeSet 都是 Set 接口的实现类,都能保证元素唯一,并且都不是线程安全的。

2. HashSetLinkedHashSetTreeSet 的主要区别在于底层数据结构不同。HashSet 的底层数据结构是哈希表(基于 HashMap 实现)。LinkedHashSet 的底层数据结构是链表和哈希表,元素的插入和取出顺序满足 FIFO。TreeSet 底层数据结构是红黑树,元素是有序的,排序的方式有自然排序和定制排序。

3. 底层数据结构不同又导致这三者的应用场景不同。HashSet 用于不需要保证元素插入和取出顺序的场景,LinkedHashSet 用于保证元素的插入和取出顺序满足 FIFO 的场景,TreeSet 用于支持对元素自定义排序规则的场景。

Queue:

PriorityQueue: Object[] 数组来实现小顶堆。

DelayQueue:PriorityQueue

ArrayDeque: 可扩容动态双向数组。

Map:

HashMap:JDK1.8 之前 HashMap 由数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。

LinkedHashMapLinkedHashMap 继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。

Hashtable:数组+链表组成的,数组是 Hashtable 的主体,链表则是主要为了解决哈希冲突而存在的。

TreeMap:红黑树(自平衡的排序二叉树)。

HashMap和HashTable的区别:

1. 线程是否安全: HashMap 是非线程安全的,Hashtable 是线程安全的,因为 Hashtable 内部的方法基本都经过synchronized 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap 吧!);

2. 效率: 因为线程安全的问题,HashMap 要比 Hashtable 效率高一点。另外,Hashtable 基本被淘汰,不要在代码中使用它;

3. 对 Null key 和 Null value 的支持: HashMap 可以存储 null 的 key 和 value,但 null 作为键只能有一个,null 作为值可以有多个;Hashtable 不允许有 null 键和 null 值,否则会抛出 NullPointerException

4. 初始容量大小和每次扩充容量大小的不同: ① 创建时如果不指定容量初始值,Hashtable 默认的初始大小为 11,之后每次扩充,容量变为原来的 2n+1。HashMap 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。② 创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为 2 的幂次方大小(HashMap 中的tableSizeFor()方法保证,下面给出了源代码)。也就是说 HashMap 总是使用 2 的幂作为哈希表的大小,后面会介绍到为什么是 2 的幂次方。

5. 底层数据结构: JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)时,将链表转化为红黑树(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树),以减少搜索时间(后文中我会结合源码对这一过程进行分析)。Hashtable 没有这样的机制。

HashMap的特性

1.HashMap存储键值对实现快速存取,允许为null。key值不可重复,若key值重复则覆盖。

2.非同步,线程不安全。

3.底层是hash表,不保证有序

HashMap的底层结构

在jdk1.8之前使用的是数组加链表

在jdk1.8以后使用的是数组加链表加红黑表

链表的作用是什么?为什么JDK8引入了红黑树?

链表主要是为了解决数组中的key发生hash冲突时,将发生碰撞的key存到链表中

红黑树主要是为了解决链表过长,的查询速度太慢问题,链表查询时间复杂度为O(n)

当链表长度大于等于8时,就会转变成红黑树,时间复杂度为O(logn)

当链表长度小于等于6时,由红黑树转变回链表,因为链表过短时引入红黑树反而会降低查询速度

HashMap扩容原理

当元素个数大于额定元素个数时,就会触发扩容。

额定元素=数组长度*负载因子(默认是0.75)

扩容后的长度为原来长度的2倍。

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值