Map-HashMap-Hashtable-TreeMap-Properties-Collections

Map-HashMap-Hashtable-TreeMap-Properties-Collections,第1张

Map-HashMap-Hashtable-TreeMap-Properties-Collections

一.Map(接口)

储存键值对类型数据

键值对:K-V映射关系

K:键->唯一的,不可重复的,无序的

Map中的所有的Key拿出来构成一个Set集合

V:值——>可重复的,无序的——>Map中的所有的键值对的value拿出来构成一个collection集合

一个key只能对应一个value,如果想要一个key对应多个value,可以将value定义为数组|集合

如果key相同,value覆盖

遍历:

        1.valus():只能遍历value,不能遍历key

        2.keyset();

        3.entryset();

二.HashMap:基于哈希表的Map接口的实现。 此实现提供了所有可选的映射 *** 作,并允许null值和null键。

        底层:哈希表(数组+链表+红黑树)

        特点:查询,增删效率高,无序的,根据key去重

        线程不安全

        默认初始容量16:哈希表数组结构第一次默认大小

        加载因子loadFactor|默认加载因子DEFAULT_LOAD_FACTOR:0.75

        大小:集合中数据的个数

        扩容临界值|阀值:size = Capacity*loadFactor实现扩容

        扩容机制:newCap = oldCap《1,每次扩容原容量的两倍

                HashSet底层是由HashMap维护的

分析源码:数组长度要求2的整数次幂

        链表长度>8,容量<64,会通过resize()进行扩容,如果容量大于64,才会把链表转变为红黑树

            1.根据key计算哈希值hash(key)   int hash = (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
            2.调用putVal(hash,key,value)实现存储键值对数据
            3.先判断哈希表中的节点数组是否为null,或者长度为0 ((tab = table) == null || (n = tab.length) == 0),如果是证明是第一次添加数据,调用resize()方法为数组扩容
            4.resize()扩容方法内部的扩容机制 int newCap = oldCap << 1,每次扩容原容量的2倍
            5.计算位桶的索引(节点数据要存储在数组的指定索引位置)  index = (n - 1) & hash
            6.判断数组对应索引位置是否存在节点数据 tab[index] == null
            7.如果没有存在数据,证明链表中没有节点,当前要存储的数据节点作为链表头节点存在,长度+1,然后判断是否需要扩容,需要扩容调用resize方法进行扩容 if (++size > threshold) {resize();}
                tab[index] = new Node<>(hash, key, value, null);
            8.如果存在数据,判断已有的节点是否为红黑树的节点,如果调用putTreeval()方法实现添加,如果不是树的节点,证明还是链表结构
              遍历链表,判断已有链表的节点的key是否与要存储的键值对的key相同(e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))),
              如果相同value覆盖,返回被覆盖的value,
              如果不相同,遍历到链表的最后,创建新节点,挂在原链表的最后 p.next = newNode(hash, key, value, null);,长度+1,判断是否需要扩容 (++size > threshold) {resize();}

存储过程中的所有的哈希算法实现,目的都是为了把数据尽量散列的分布在不同的位桶中,减少哈希碰撞,提高效率。

注意:Map的去重根据key实现,HashMap的哈希表中计算位桶的索引,判断是否重复都是根据key与value无关,只有存储数据,构建新节点的时候或者key相同value覆盖的时候才与value有关

去重:HashMap中键值对的key为JavaBean的时候要求key的类型重写Hashcode和equals方法

三:Hashtable:

底层结构:哈希表

HashMap和Hashtable的区别:

1.继承体系不同

2储存键值对中对null值的要求不同

        HashMap中null值可以作为键值对

        Hashtable中null值不能作为键值对

3.同步情况不同

        HashMap线程不安全,不同步

        Hashtable线程安全的哈希表

4.初始容量,扩容机制不同

        HashMap初始容量16,扩容:每次扩容原容量2倍

        Hashtable初始容量10,扩容:每次扩容原容量2倍加1

5.计算key的hash值,与位桶索引的方式不同

                HashMap :
                int hash = (h = key.hashCode()) ^ (h >>> 16);
                int index = (n - 1) & hash;
                Hashtable :
                 int hash = key.hashCode();
                 int index = (hash & 0x7FFFFFFF) % tab.length;

HashMap线程不安全问题:

1.可以使用Hashtable

2.Collections工具类中 synchronizedmap(Mapm)

3.juc高级并发编程包ConcurrentHashMap——>推荐使用

四.TreeMap:

        底层结构:红黑树

        特点:自动做升序排列,无序的,去重的

        

        注意:无论是排序,还是去重都是根据键值对的key计算。

        排列去重问题:都是根据键值对的key实现,要求key的类型实现内部比较器,或者定义TreeMap指定使用外部比较器

TreeSet底层就是由TreeMap维护的,就是TreeMap键值对的key

五.properties:

        Properties类表示一组持久的属性。 Properties可以保存到流中或从流中加载。 属性列表中的每个键及其对应的值都是一个字符串。

properties常用作配置文件使用

定义使用步骤:

        1.src下新建文件 xx.properties
        2.创建Properties类型的对象
        3.调用load(InputStream|Reader)
        4.根据key获取value  getProperty(key)

六.Collections 工具类

        此类仅包含对集合进行 *** 作或返回集合的静态方法

        静态工厂

        类似Arrays

Collection与Collections的区别:

Collection是一个集合接口

Collections是实现Collection的工具类

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5574173.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存