Java之Set、List、Map内容整理

一:Set

Set接口继承自Collection,存储的数据无序,不可重复。Set有三个常用实现类:HashSet、TreeSet、LinkedHashSet。三个实现类都是线程不安全的。

(1) HashSet:一般单纯用来存储无序且无重复的数据。底层基于HashMap,所以底层数据结构是数组+链表,和HashMap一样通过hashcode()、equals()方法保证数据无重复。

(2)LinkedHashSet:LinkedHashSet继承自HashSet,它们之间的不同在于LinkedHashSet除了使用数组+链表来存储无重复的数据,还构建了一个双向链表来保证数据的插入有序,即通过链表将数据连接起来,保证数据的输入顺序和输出顺序一致。

(3)TreeSet:TreeSet主要用来将一组数据进行大小排序(通过比较Key对象的大小),而不是单纯的用于存储数据。底层数据结构是红黑树。

 

二:List

List接口也是继承自Collection,存储的数据有序,可重复。List有三个实现类:ArrayList、LinkedList、Vector。Vector是线程安全的,但是由于效率低被弃用了,ArrayList和LinkedList是线程不安全的,但效率高。

(1)ArrayList:ArrayList底层数据结构是数组,具有数组的优缺点:查询操作很快,增删操作很慢。

(2)LinkedList:LinkedList底层数据结构是双向链表,具有链表的优缺点:增删操作很快,查询操作很慢。

 

三:Map

Map接口常用的实现类有:HashMap、TreeMap、LinkedHashMap。存储的数据是键值对。这三个都是线程不安全的。

(1)HashMap:底层数据结构是数组+链表。数组用来存放数据,链表用来解决数据存储冲突。

        1) 实现原理:首先调用Key对象的hashcode()方法,返回的是一个int型的hashcode值;然后将其作为参数传入hash()方法。hash()方法里将hashcode值右移一定位数后与本身进行异或操作,主要作用是混淆hashcode值的高低位,可以有效减少冲突。最后hash()方法返回的hash值与数组长度进行取模运算得到该数据在数组的存储下标(由于计算机中取模运算比较复杂,当数组长度为2的n次幂时可以通过hash值与数组长度-1进行位与运算得到数组下标)。如果该数组下标没有存储数据,就将该数据直接写入数组;如果数组下标已经存储了数据,就通过equals()方法来与该数组下标以及对应的链表里存储的数据进行比较,相同则覆盖原数据,不相同则存储该数据。

       2)注意事项:1.HashMap的数组初始大小为16,负载因子为0.75,当数组中存储的数据超过16*0.75=12个时就需要扩容,一般是扩容成原来的2倍大小,然后再对存储的数据进行重哈希定位并存储。2.当链表的长度超过8的时候,一般将该链表转为红黑树来存储冲突数据,能够有效提高效率。

      3)哈希冲突:在HashMap里是通过链地址法来解决hash冲突问题,即构造链表来存储冲突的数据。除了该方法之外常用的解决冲突方法有:开放定址法、重哈希法、公共溢出区法。

(2)LinkedHashMap:同LinkedHashSet类似(其实LinkedHashSet就是基于LinkedHashMap的),LinkedHashMap继承自HashMap,底层数据结构除了使用数组+链表来存储数据之外,还有一个双向链表来保证数据的插入有序。

(3)TreeMap:同TreeSet类似(TreeSet也是基于TreeMap的),TreeMap主要用途也是用于数据大小排序的。底层数据结构是红黑树。

综上所述,其实Set的三个实现类和Map的三个实现类是一一对应的,主要区别在于Map存储的是键值对,而Set里的值设为没有意义的Object对象,主要用来存储Key键。

 

其他问题:

1.HashMap和HashTable的区别:两者很相似,除了以下几点:

        (1)HashTable继承自Dictionary;HashMap继承自AbstractMap。

        (2)HashTable是同步的,所以是线程安全的,但是效率低;HashMap不是同步的,是线程不安全的,但是效率高。(HashMap可以使用Collections的Synchronized()方法来达到线程安全)

        (3)HashMap的键和值可以是Null,而HashTable的键和值不可以为Null

2.CurrentHashMap:由于HashMap线程不安全而HashTable效率又低,所以产生了CurrentHashMap。CurrentHashMap和HashTable的区别在于同步锁的不同:HashTable将整个存储数组完全锁住,当一个线程访问HashTable数组里的数据时,其他线程都不可访问该数组,所以效率低。而CurrentHashMap通过分段锁来实现同步操作,将存储数组分为几段,当一个线程访问数组中一个段的数据时,其他线程可以访问数组其他段的数据,从而提高了效率。

3.WeakHashMap:WeakHashMap也是继承自AbsTractMap,主要功能和HashMap类似,区别在于WeakHashMap中的键是“弱键”,所谓“弱键”,即当该键不再被使用时,GC垃圾回收器会将该弱键对应的键值对进行回收,具体原理为:当WeakHashMap中某个弱键不再被引用时,GC会回收该弱键内存,并且该弱键会被保存到一个队列中,下一次队WeakHashMap进行操作时,会先同步存储数组和队列,从存储数组中删除队列中弱键对应的键值对。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值