java中的Map接口(四)

目录

一、框架

二、Map结构的理解:

三、HashMap的底层实现原理

四、LinkedHashMap的底层实现原理(了解)

五:Map中定义的方法:

面试题:


 

一、框架

 /----Map接口:双列集合,用来存储一对一对的数据。(key、value)(函数)
      /----HashMap:作为Map的主要实现类;线程不安全的,效率高;存储nuLl的key和value
          /----LinkedHashMap:在原有的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个元素.从而保证在遍历map元素时,可以按照添加的顺序实现遍历。对于频繁的遍历操作,效率更高。
      /----TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然排序或定制排序(key可以是一个类的对象,对象中有多个属性)
      /----Hashtable:作为古老的实现类;线程安全的,效率低;不能存储null的key和vaLue
          /----Properties:常用来处理配置文件。key和vaLue都是String类型

 HashMap的底层:      数组+链表           jdk7及之前
                  数组+链表+红黑树       jdk 8

二、Map结构的理解:

    Map中的key:无序的、不可重复的,使用set存储所有的key —————>这就要求key存在的类中重写了equals()和HashCode()  (以HashMap为例)(Tree中就是要写comparTo)
    Map中的value:无序的、可重复的,使用coLlection存储所有的vaLue一个键值对: key-vaLue构成了一个Entry对象。—————>value所在的类要重写equals()
    Map中的entry:无序的、不可重复的,使用set存储所有的entry

三、HashMap的底层实现原理

以jdk7为例说明:

 HashMap map = new HashMap( ):
 在实例化以后,底层创建了长度是16的一维数组Entry[] table。...可能已经执行过多次put. . .
 map.put( key1, value1):
 首先,调用key1所在类的hashcode()计算key1哈希值,此哈希值经过某种算如果此位置上的数据为空,此时的key1-value1添加成功。----情况一
     如果此位置上的数据不为空,(意味着此位置上存在一个或多个数据(以链表形式存在),比较ez1和已经存在的一个或多个数8的哈希值:
     如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1添加成功。----情况二
     如果key1的哈希值和已经存在的某一个数据(key2-vaLue2)的哈希值相同,继续比较:调用key1所在类的equals(key2)
         如果equals()返回false:此时key1-vaLue1添加成功。----情况三
         如果equaLs()返回true:使用value1替换value2。(相当于修改了原来的entry中的value值)

补充:关于情况2和情况3:此时key1-value1和原来的数据以链表的方式存储。

 在不断的添加过程中,会涉及到扩容问题,当超出临界值且要存放的位置非空时,需要进行扩容操作,
 默认的扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来。

jdk8 相较于jdk7在底层实现方面的不同:
  1. new HashMap():底层没有创建一个长度为16的数组
  2.jdk8底层的数组是:Node[],而非Entry[]
  3.首次调用put()方法时,底层创建长度为16的数组
  4. jdk7底层结构只有:数组+链表。
     jdk8中底层结构:数组+链表+红黑树。
    当数组的某一个索引位置上的元素以链表形式存在的数据个数>8且当前数组的长度>64时,(前者调出是否扩容的判断,但是如果不满足后者时,那就扩容来解决)
      此时此索引位置上的所有数据改为使用红黑树存储。   目的是:遍历快。
DEFAULT_INITIAL_CAPACITY : HashMap的默认容量:16
      DEFAULT_LOAD_FACTOR: HashMap的默认加载因子:0.75
      threshold:扩容的临界值,=容量*填充因子:16*0.75 =>12
      TREEIFY_THRESHOLD: Bucket中链表长度大于该默认值,转化为红黑树:8
      MIN_TREETFY_CAPACITY:桶中的Node被树化时最小的hash表容量:64

四、LinkedHashMap的底层实现原理(了解)

        作为HashMap的子类,在newNode时调用的时自己重写的方法,new了一个Entry(Node的子类),多了一组before,after
      
源码中:
      static class Entry<K,V> extends HashMap. Node<K,V> i
      Entry<K,V> before,after;//能够记录添加的元素的先后顺序Entry(int hash,K key, v value,Node<K,V>next) i
      super( hash,key, value, next);
小知识:hashSet中存放元素其实存放到了HashMap中的key中,其value为一个静态的new Object(),所有key都指向它,也没啥实际意义。

五:Map中定义的方法:

添加、删除、修改操作:
 object put(object key,object value):将指定key-value添加到(或修改)当前map对象中
 void putALL (Map m):将m中的所有key-value对存放到当前map中
 object remove(object key):移除指定key的key-value对,并返回value
 void clear():清空当前map中的所有数据
 元素查询的操作:
 object get(object key产:获取指定key对应的value
 booLean containsKey(object key):是否包含指定的key
 boolean containsvalue(object value):是否包含指定的
 valueint size():返回map 中key-value对的个数
 boolean isEmpty():判断当前map是否为空
 boolean equals(object obj):判断当前map和参数对象obj是否相等
 元视图操作的方法:
 set keyset():返回所有key构成的Set集合
 collection values():返回所有value构成的coLlection集合
 Set entrySet():返回所有key-vaLue对构成的Set集合

 总结:常用方法:
 添加: put(object key , object value)
 删除:remove(object key)
 修改: put(object key, object value)
 查询: get(object key)
 长度:size()
 遍历:keyset() / values() / entrySet()

遍历Map中的元素(一般都是取出key或者value),代码演示:

public class MapTest {

    @Test
    public void test1() {
        HashMap hashMap = new HashMap();
        hashMap.put("aa", 123);
        hashMap.put("bb", 8);
        hashMap.put("ff", 44);
        hashMap.put("ss", 66);

//        方式一:返回的set进行捕获,然后就能使用collection中的遍历方法了
        Set set = hashMap.keySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();//这就是key
            Object o = hashMap.get(next);//这就是value
            System.out.println(next + "==" + o);
        }
//         方式二:entrySet()
        Set set1 = hashMap.entrySet();
        Iterator iterator1 = set1.iterator();
        while (iterator1.hasNext()) {
            Object next1 = iterator1.next();
            Map.Entry entry = (Map.Entry) next1;//强转为Map.Entry类型的
            System.out.println(entry.getKey() + "==" + entry.getValue());
        }
    }
}

面试题:

1. HashMap的底层实现原理?

2. HashMap和Hashtable的异同?

3. CurrentHashMap 与HashtabLe的异同?(暂时不讲)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java塑造中...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值