开发随手记-Collection中Set、List、Map理解?

               list 、set、 map区别:意思不同、用途不同。

意思不同

  • List:有序、可重复。
  • Set:无序、不可重复的集合。重复元素会覆盖掉。
  • Map:键值对,键唯一、值不唯一。Map 集合中存储的是键值对,键不能重复,值可以重复。

用途不同 

  • List 集合中对象按照索引位置排序,可以有重复对象,允许按照对象在集合中的索引位置检索对象。
  • Map中的每一个元素包含一个键和一个值,成对出现,键对象不可以重复,值对象可以重复。
  • Set 集合中的对象不按照特定的方式排序,并且没有重复对象,但它的实现类能对集合中的对象按照特定的方式排序。

 list

        ArrayList

        ArrayList底层是数组,初始容量为10,当使用空参构造器创建对象时对象此时的容量并不是10,当使用add给对象赋值操作时
        此时的容量为10。当数组要满了就自动扩容为原容量的1.5倍。

        LinkedList

        LinkedList不用扩容,因为它实现了Dqueue和LIst接口,底层是用双向链表实现的,所以它对元素的增加、删除效率要比ArrayList好;
        它是一个双向链表,没有初始化大小,也没有扩容的机制,就是一直在前面或者后面新增就好

        List 的区别
类型底层实现是否线程安全扩容方式是否允许添加 null 元素功能
ArrayList是数组线程不安全初始容量是 10,扩容因子是 0.5,超出现有长度后,自动扩容,扩容的容量最小是1.5倍允许添加 null 元素允许重复的元素,查询快,增删慢
LinkedList链表线程不安全它是一个双向链表,没有初始化大小,也没有扩容的机制,就是一直在前面或者后面新增就好允许添加 null 元素允许重复的元素,查询慢,增删快
Vector是数组线程安全Vector默认初始容量为10,扩容因子是 1,自动扩容,扩容的容量最小是2倍允许添加 null 元素允许重复的元素,查询快,增删慢

set

        HashSet

        HashSet底层是Hashmap即数组+链表,添加元素时,table数组扩容为16,加载因子为0.75,所以临界值为16 * 0.75 = 12,意思是添加12个元素后,table数组将继续扩容至原来的2倍即32,临界值也会变为32 * 0.75 = 24,以此类推。
2、HashSet转成红黑树机制结论
        当一条链表的元素得到8个之后,并且table数组的大小达到64,链表就转成红黑树,如果table数组未到64,table数组将扩容至原来的2倍,直至大小达到64链表转成红黑树为止。

       Set的区别

注意:一条链表的元素个数达到默认值(8),并且数组的大小大于默认值(64),此链表就会进行树化(红黑树),数组的大小就行hashSet中所有元素的个数。
HashMap 底层维护了Node类型的数组table,默认为null

类型底层实现是否线程安全扩容方式是否允许添加 null 元素功能
HashSetHashSet的底层是基于HashMap实现的,HashSet底层是Hashmap即数组+(链表或者红黑树)线程不安全添加元素时,table数组扩容为16,加载因子为0.75,所以临界值为16 * 0.75 = 12,意思是添加12个元素后,table数组将继续扩容至原来的2倍即32,临界值也会变为32 * 0.75 = 24允许添加 null 元素不允许重复的元素,查询快,增删快,无序集合
LinkedHashSet底层数据结构是LinkedHashMap,同时维护一个双向链表来保证元素的顺序(多增加一个双向链表)线程不安全初始容量为16,需要扩容table容量为16,临界值为12,以后再次扩容,则需要扩容table容量为原来的2倍允许添加 null 元素不允许重复的元素,查询快,增删快,有序集合
TreeSet有序的集合,基于TreeMap实现(底层的数据结构是红黑树),支持两种排序方式:自然排序和定制排序线程不安全当TreeSet中的元素个数达到它的容量时,会自动进行扩容,将容量翻倍不允许添加 null 元素不允许重复的元素,查询快,增删快,有序集合

Map

        HashMap

        HashMap的初始容量为16,扩容因子为0.75,扩容为原来容量的两倍。

        HashMap:它是最常用的Map实现类之一,它使用哈希表来存储键值对。它不保证元素的顺序,因此在迭代时不能保证顺序。它允许null键和值,但不保证线程安全。

        TreeMap

        TreeMap:它是基于红黑树实现的,它可以保证元素按照键的自然顺序排序。它不允许null键,但允许null值。它也不是线程安全的。

        LinkedHashMap

         LinkedHashMap:它是HashMap的一个子类,它通过维护一个双向链表来保证元素的顺序。它既可以按照插入顺序迭代,也可以按照访问顺序迭代(即最近访问的元素排在最前面)。它允许null键和值,但不保证线程安全。

        ConcurrentHashMap

        oncurrentHashMap:它是线程安全的HashMap实现类,它使用分段锁来实现并发访问。它的性能比Hashtable好,并且允许null键和值。它也可以按照插入顺序迭代。

底层采用:CAS + synchronized 来保证并发安全性。

Map的区别
类型底层实现是否线程安全扩容方式是否允许添加 null 元素功能
HashMapjdk1.7采用数组+链表;jdk1.8 采用数组+红黑树线程不安全HashMap默认的初始化大小为16。之后每次扩充,容量变为原来的2倍允许key添加一个null元素查询快,增删快,无序集合
LinkedHashMap是继承 HashMap 的,底层是数组(哈希表)+链表/红黑树,并自己维持了一个双向链表,按照插入顺序进行访问,实现了LRU算法线程不安全LinkedHashMap 的扩容方式跟 HashMap 相同,当元素个数达到阈值时,会将数组容量扩大2倍允许key添加一个null元素查询快,增删快,有序集合
CocurrentHashMapjdk1.7:Segments数组+ReentrantHashMap(作为互斥锁来控制并发访问)+链表,采用分段锁保证安全性;jdk1.8:Striped locking(算法来实现互斥锁控制,避免了使用synchronized关键字对整个HashMap进行加锁的效率问题,提高了并发度和性能表现) + CAS算法 +红黑树线程安全当链表中元素个数超过默认设定(8个),当数组的大小还未超过64的时候,此时进行数组的扩容,如果超过则将链表转化成红黑树不允许null键和值查询快,增删快,无序集合(ConcurrentHashMap是线程安全的数组,是HashTable的替代品,同为线程安全,其性能要比HashTable更好)
HashTable底层通过数组+链表的方式实现线程安全(通过synchronized关键字实现线程安全)创建时如果不指定容量初始值,Hashtable默认的初始大小为11,之后每次扩容,容量变为原来的2n+1允许null值作为key和value查询快,增删快,无序集合
TreeMap基于红黑树实现线程不安全新底层数组的长度是原长度的2倍key 不可以存入null查询快,增删快,有序集合

注意:Android 中常用的 map 集合:

类型底层实现是否线程安全扩容方式是否允许添加 null 元素功能
ArrayMapArrayMap 的底层实现基于数组和红黑树,适用于小型数据集线程不安全每次扩容时的新数组大小是原有数组大小的2倍可以添加null元素查询快,增删快,有序集合(相比HashMap内存空间占用更少)
SparseArray它的底层实现主要依赖于两个数据结构:一个数组和一个 Map线程不安全每次扩容时的新数组大小是原有数组大小的2倍允许存储null元素查询快,增删快,有序集合(Key 是 int 是代替 HashMap)
hashMap和LinkedHashMap区别

HashMap和LinkedHashMap都是Java集合框架中的Map接口的实现类,其中HashMap基于哈希表实现,而LinkedHashMap则继承自HashMap,底层使用哈希表和双向链表结合的方式实现。它们之间的区别主要体现在以下几个方面:

-插入顺序:HashMap不保证映射的顺序,而LinkedHashMap会根据元素插入的顺序维护一个双向链表,因此保证了映射的顺序,可以通过get操作访问元素的插入顺序。

  • 迭代顺序:LinkedHashMap迭代元素的顺序是插入顺序,而HashMap的迭代顺序是随机的。
  • 性能:由于LinkedHashMap在底层额外维护了一个双向链表,因此在插入或删除元素时需要更多的操作,因此HashMap的性能通常比LinkedHashMap要高。
  • 内存占用:由于LinkedHashMap维护了一个双向链表,因此它的内存占用通常比HashMap要高一些。

综上,如果需要维护元素的插入顺序或者迭代顺序,并且对性能和内存占用要求不是非常高,可以选择使用LinkedHashMap。如果只关心键值对的映射关系,对性能和内存占用有较高要求的话,可以选择使用HashMap。

hashMap和TreeMap区别

HashMap和TreeMap都是Java中的集合类,其中HashMap是基于哈希表实现的,而TreeMap则是基于红黑树实现的。它们之间的区别主要体现在以下几个方面:

  • 插入顺序:HashMap不保证映射的顺序,而TreeMap会根据元素的键值进行排序,因此保证了映射的顺序。
  • 元素访问时间复杂度:HashMap的元素访问时间复杂度是常数级别的,即O(1),而TreeMap的元素访问时间复杂度是基于红黑树的复杂度,通常是O(log(n))。
  • 键的类型:HashMap可以使用任何类型的对象作为键,只要它们能正确的实现hashCode()和equals()方法,而TreeMap的键必须实现Comparable接口或提供自定义的Comparator比较器来进行比较。
  • 内存占用:由于TreeMap需要维护红黑树的结构,因此它的内存占用相对较高。而HashMap在元素较少时,占用内存较小。

综上,如果需要按照键值对的键进行排序访问元素,可以选择使用TreeMap。如果只关心键值对的映射关系,对元素访问速度和内存占用要求较高的话,可以选择使用HashMap。

hashMap和CocurrentHashMap区别

HashMap和ConcurrentHashMap都是Java中的集合类,但它们之间有以下区别:

  • 线程安全性:HashMap是非线程安全的,而ConcurrentHashMap是线程安全的,多个线程可以同时读写ConcurrentHashMap的不同部分。
  • 内部实现方式:HashMap是基于哈希表实现的,而ConcurrentHashMap是基于分段锁实现的,它将整个Map拆分成多个“段”,其中每个段都有自己的锁,不同的线程可以同时访问不同的段,从而提高并发性能。
  • 迭代器支持:在使用Iterator迭代器遍历HashMap时,如果在遍历过程中对HashMap进行了修改操作,会抛出ConcurrentModificationException异常。而在ConcurrentHashMap中,它支持在并发修改的情况下安全的使用迭代器进行遍历操作,而不会抛出异常。
  • 数据一致性:在进行并发读写的情况下,HashMap不能保证数据的一致性,而ConcurrentHashMap能够保证更新操作之后的读操作能够看到更新后的数据。

综上,如果需要在多线程环境下访问Map,建议使用ConcurrentHashMap,它提供了更好的并发性能和线程安全性,而如果是单线程环境下访问Map,可以使用HashMap。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值