Java集合类

ArrayList和LinkList

ArrayList和LinkList都是实现了List的接口类。

ArrayList在末尾添加和删除的时间是一样的,中间部分的增删所需时间大大增加。根据索引查找元素的速度大大加快。

LinkList插入和删除集合中在任何位置元素花费的时间都是一样的,根据索引查找一个元素的时间较长。

原因是ArrayList的实现是基于数组,LinkList的实现是基于链表,对于随机访问的get set方法 ,ArrayList是要优于LinkList的,因为LinkList要移动指针。对于新增和删除操作。add remove,LinkList比较占优势,因为ArrayList要移动数据。、

HashMap

HashMap是数组和链表的结合体,在java1.8当链表节点较少时仍以链表的形式存在,大于8时会转化为红黑树。在储存空间中以键值对的形式存在。

线程安全

HashMap是线程不安全的。通过Collections.synchronizedMap(hashMap)可以让HashMap同步。synchronizedMap方法返回一个SynchronziedMap类的对象,而在synchronzied使用了synchronzied来保证对map的操作时线程安全的。

可以使用HashTable代替HashMap,HashTable是线程安全的,HashTable当一个线程访问同步方法时,会被阻塞住,不但不可以使用put方法,连get方法也不可以,效率很低,基本上不会使用。也可以使用jdk1.5之后的ConcurrentHashMap代替HashTable,他的同步性更好,他可以根据同步级别对map一部分上锁,但是HashTable提供更强的线程安全性。

为什么HashMap是线程不安全的

当多个线程同时使用put方法添加元素的时候,正好有两个put的key发生了碰撞,那么根据HashMap的实现,这两个键都会添加到bucket数组的同一个位置,这样会使一个线程的put数据被覆盖掉。

如果两个线程同时发现元素个数超过了负载因子,这样多个线程就会同时对hash数组进行扩容,都在重新计算元素位置,以及复制数据,但是最终只有一个线程扩容后的数组会赋给table,其他线程都会丢失,各自线程put的数据也会丢失,并且会引起死循环。

碰撞问题

两个键值得hashcode相同,就会发生碰撞。HashMap使用链表来存储对象,hashcode相同bucket就相同。使用不可变的,声明为final的对象,采用合适的equals和hashcode方法将会减少碰撞的发生,提高效率。

两个键的hashcode相同,如何获取值对象。当调用get方法,HashMap会使用键对象的hashcode找到bucket的位置,再调用keys.equals方法找到链表中正确的节点

为什么String,Integer这种封装类适合作为键,String是不可变的也是final的,而且已经重写了hashcode和equals,要计算hash

code就要防止键值改变,如果键在放入时和获取时返回不同的hashcode,那么就不能从HashMap找到想要的对象。而且String也是线程安全的。

扩容问题

HashMap超过了负载因子定义的长度就会进行扩容。默认的负载因子大小为0.75,当容量超过原容量大小 * 负载因子时将会创建原来HashMap大小两倍的bucket数组来重新调整map大小,并将原来的对象放入新的bucket数组中,这个过程叫做rehashing,因为他调用hash方法找到新的bucket位置。

扩容是一个相当耗时的操作,他需要重新计算这些元素在新的数组中位置并进行复制处理,在定义HashMap时最好提前预告元素个数,有助于提高性能。默认容量是16。

HashSet

HashSet实现了Set接口,不允许集合中存在重复值,对象判断是否重复是通过equals 和 hashcode。保存对象之前如果没有重写hashcode和equals方法,在对比的时候回调用默认的实现。

HashSet使用对象计算hashcode值,HashMap使用键对象计算hashcode值。

TreeMap

TreeMap是有顺序的,HashMap的储存是以键值对的形式存在的,允许建和值为null。

HashTable

HashTable的初始大小和HashMap不一样是因为HashTable的扩容方法是乘2加1,保证了容量是奇数。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值