Set 和 Map

集合Set:   元素无序(元素的存取顺序不一致)

                 元素不重复(元素重写了 hashCode() 和 equals()方法 )

 

Set的三个常用子类: 

    1) HashSet:   底层数据结构是 哈希表

                                           特点: 元素是无序的,元素唯一性(重写 hashCode() 和 equals() 方法),

                                                      线程不安全(不同步),允许键入 null 值

    2) LinkedHashSet:    底层数据结构是 链表 和 哈希表 

                                          特点:  链表保证了元素的有序(存取顺序一致) 

                                                       哈希表保证了元素的唯一性(重写了 hashCode() 和 equals() 方法)

                                                       线程不安全(不同步),允许键入 null 值

    3)TreeSet:底层数据结构是 二叉树

                                         特点:元素唯一并且可以自定义元素的排列顺序

                                                   线程不安全(不同步),不能键入 null 值

        TreeSet 自定义比较的两种方式:

                 方式一: 通过 TreeSet() 的无参构造 + 元素实现 Comparable接口

                                并重写 它的 compareTo() ,通过返回的整数的     0 来排序元素

                                而且元素必须重写  hashCode() 和 equals()(自动生成)

                 方式二 : 通过 TreeSet(  Comparator<? super E> comparator 的有参构造

                               并且重写Comparator接口中的 compare( ) 方法 来自定义排列顺序

                               通过返回的整数的     0 来排序元素

                              

     

 Map集合: 

                           双列集合,里面存的是映射关系(键值对)

                            Map集合的所有数据结构只与 键 有关,且键唯一

                            一个键只能对应一个值,当键相同时,值被覆盖

 

            Map的功能:

                            1)添加功能 
                                                 V    put(K key,V value):添加元素。还相当于替换
                                                                                     如果键是第一次存储,就直接存储元素,返回 null
                                                                                     如果键不是第一次存在,就用值把以前的值替换掉,并返回以前的值
                            2)删除功能
                                                void clear():    移除所有的键值对元素
                                                V remove(Object key):根据 键 删除 键值对元素,并把 返回
                             3)判断功能
                                                boolean containsKey(Object key):     判断集合是否包含指定的
                                                boolean containsValue(Object value):  判断集合是否包含指定的
                                                boolean isEmpty(): 判断集合是否为空
                              4)获取功能
                                                Set<Map.Entry<K,V>> entrySet():    返回一个 键值对 的Set集合(用于遍历集合 方式一)
                                                Set<K> keySet():   获取集合中所有 的集合  (用于遍历集合 方式二)
                                                Collection<V> values():    获取集合中所有值的集合

                                                V get(Object key):    根据键获取值
                              5)长度功能
                                                int size():返回集合中的键值对的对数

 

Map的子集合: Map集合的数据结构都只与    有关,与值无关

                 HashMap:  

                                     底层的数据结构是 哈希表

                                     元素无序 (存取顺序不一致),且唯一(重写 hashCode() 和 equals() 方法)

                                     线程不安全(非同步),但效率

                                     允许存入 null 键 和 null 

 

                 LinkedHashMap: 

                                    底层数据结构是 链表 和 哈希表

                                    元素有序(存取顺序一致,链表结构),且唯一(哈希表 重写 hashCode() 和 equals()方法 )

                                    线程不安全(非同步),但效率

                                    允许存入 null 键 和 null 值

 

                 TreeMap: 

                                   底层数据结构是  二叉树

                                   元素唯一,并且可以自己定义排列顺序(自然排序 / 比较器排序)

                                   线程不安全,但效率高

                                   不允许存入 null 键,  但允许存入 null 值

 

             TreeMap必须实现的排序方式:

                        1)自然排序:  TreeMap()的无参构造函数  +  元素类实现 Comparable 接口,并重写其中的 compareTo() 方法

                        2)比较器排序:TreeMap( Comparator< ? super E >comparator ) 有参构造 + 重写该接口的 compare() 方法    

 

*********面试题: 

          HashTable 与 HashMap 的区别?

                1)HashMap 线程不安全( 非同步的),效率高

                      HashTable线程安全(同步的),效率低

                2)HashMap 允许存入 null 键 和 null 值

                      HashTable不允许存入 null 键 和 null 值

                3 )   初始容量大小和每次扩充容量大小的不同 : 

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

                4 ) 底层数据结构: JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)                                                    时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。              

                5)HashMap 实现 Map接口

                      HashTable 也实现了Map接口,继承自Dictionary类

                6)HashMap 有 containsKey() 和 containsValue() 方法

                      HashTable只有 contains()方法,容易引起误会使用       

 

**********HashMap 与 HashSet 的区别:

       

HashMap 原理: 

            HashMap是基于哈希表的Map接口的非同步实现.在Java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造,HashMap也不例外.HashMap实际上是一个”链表的数组”的数据结构,每个元素存放链表头结点的数组,即数组和链表的结合体.HashMap底层就是一个数组结构,数组中的每一项又是一个链表.当新建一个HashMap的时候,就会初始化一个数组,Entry就是数组中的元素,每个Map.Entry其实就是一个key-value对,它持有一个指向下一个元素的引用,就构成了链表. 

 

HashTable原理:

          Hashtable是基于哈希表的实现.通过使用put(Object key,Object value)方法把两个对象进行关联,需要时用get(Object key)取得与key关联的值对象.还可以查询某个对象的索引值等等.这里的get方法查找一个对象时与Vector中的get方法在内部实现时有很大不同,在一个Hashtable中查找一个键对象要比在一个Vector中快的多.这是因为Hashtable使用了一种哈希表的技术,在Java每个对象缺省都有一个通过Object的hashCode()方法获得的哈希码,Hashtable就是利用这个哈希码实现快速查找键对象的. 

 

HashMap的底层实现

JDK1.8之前

JDK1.8 之前 HashMap 由 数组+链表 组成的(“链表散列” 即数组和链表的结合体),数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(HashMap 采用 “拉链法也就是链地址法” 解决冲突),如果定位到的数组位置不含链表(当前 entry 的 next 指向 null ),那么对于查找,添加等操作很快,仅需一次寻址即可;如果定位到的数组包含链表,对于添加操作,其时间复杂度依然为 O(1),因为最新的 Entry 会插入链表头部,即需要简单改变引用链即可,而对于查找操作来讲,此时就需要遍历链表,然后通过 key 对象的 equals 方法逐一比对查找.

                                                     

所谓 “拉链法” 就是将链表和数组相结合。也就是说创建一个链表数组,数组中每一格就是一个链表。若遇到哈希冲突,则将冲突的值加到链表中即可。

 

JDK1.8之后

相比于之前的版本, JDK1.8之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。

                 

 

TreeMap、TreeSet以及JDK1.8之后的HashMap底层都用到了红黑树。红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。

   

集合工具类Collections:针对集合操作的工具类

            常用方法:     

                     public static <T> void sort(List<T> list):                              排序,默认按照自然顺序
                     public static <T> int binarySearch(List<?> list,T key):        二分查找
                     public static <T> T max(Collection<?> coll):                       获取最大值
                     public static void reverse(List<?> list):                                反转
                     public static void shuffle(List<?> list):                                  随机置换(应用:斗地主的洗牌功能)

            

集合框架图解:

             

回答: ES6中的SetMap是两种新增的集合类型。Set是一种无重复值的集合,可以通过new Set()来创建。它具有add方法用于向集合中添加元素,has方法用于判断集合中是否存在某个元素,clear方法用于清空集合。Set也可以用于数组去重,通过new Set(\[...\])的方式将数组转换为Set,利用Set的特性去除重复值。\[1\] Map是一种键值对的集合,可以通过new Map()来创建。它具有set方法用于向集合中添加键值对,get方法用于获取指定键名对应的值,has方法用于判断集合中是否存在某个键名,clear方法用于清空集合。Map的键名可以是任意数据类型,包括引用值,但需要注意的是,引用值作为键名时,需要使用相同的引用地址才能获取到对应的值。\[2\] SetMap都可以使用for...of循环或forEach方法进行遍历。在Set中,forEach的第二个参数是集合的元素,因为Set中不存在下标。而在Map中,forEach的第一个参数是键值对的值,第二个参数是键值对的键名。\[3\] 总结来说,SetMap是ES6中新增的集合类型,Set用于存储无重复值的集合,Map用于存储键值对的集合。它们提供了一些方法来操作集合,如添加、获取、判断是否存在等。在使用时需要注意它们的特性和方法的使用方式。 #### 引用[.reference_title] - *1* *2* [ES6中的MapSet详解](https://blog.csdn.net/m0_45093055/article/details/126430467)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [ES6中的setmap](https://blog.csdn.net/weixin_44247866/article/details/127561391)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值