双例集合Map,HashMap常用方法及源码分析

Map:采用key_value存储数据,

 Map接口:存储的是一对一对的数据,采用key-value存放
      |---->HashMap:主要实现类,线程不安全,效率高;允许添加null的key或null的value
            |------>LinkedHashMap:HashMap的子类,可以实现按照添加1的顺序实现遍历
                     对于频繁的遍历操作,建议使用此接口实现类
    |---->TreeMap:可以按照元素的指定属性的大小实现遍历
    |---->HashTable:古老实现类.线程安全,效率低,不允许添加null的key或null的value
           |---->properties:常用来处理属性文件,key和value都是String类型

  Map的结构:<1.Map中的key是无序的,不可重复的,key构成的集合是Set
                <2.Map中的value是无序的,可以重复的,value构成的集合是Collection
                <3.Map中的键值构成一个entry
                <4.Map中的entry是一个set集合,无序,不可重读的

Map的常用方法:
  :put(Object key, Object value)将指定的key-value添加到map对象 ,putAll(Map m)将m中的所有键值对返回map中去
  :remove(Object,key)指定移除对应key的key-value对,并返回value
  :put(Object key,Object value)将指定的key-value修改到map对象
  :get(Object key):获取指定key的value containsValue(Object value)是否包含指定的value
  长度:size()
  遍历:KeySet()返回所有key构成的set集合 values()返回所有Value值构成的Collection集合  enterySet()返回所有的key-      vlaue构成的set集合

 

HashMap:

  HashMap的底层实现
              jdk7:数组+单向链表,底层生成Entry[ ]数组
      HashMap map =new HashMap();//Entry[] table=new Entry[16];
  ........
      map.put(key1,vlaue1);//key1-value1会封装到一个entry对象中,将此对象放于table数组中,

  首先根据key1所在的类的hashCode方法,计算key1的哈希值1,然后通过某种算法,生成得到哈希值2,

  再使用IndexOf()方法获得它在底层table数组的存放位置
  总结:先成底层空间为16的数组,在存放第一个数据时,生成特有的哈希值1,经由算法生成哈希值2,

    去操作indexOf()方法得到他的存放位置

  1.   如果index位置是哪个没有元素,则key1-value1,添加成功
  2.   如果index位置上有(key2-value2),则比较key1和key2的哈希值
    1.       ----->两者哈希值不同,则添加成功,此时数据存放在数组的位置上
    2.       ----->两者哈希值相同,比较可以所在类的equals方法,将key2作为参数传递到此方法中,比较两个key是否相同,若相同则将value2替换value1,在插入到当前的index位置 ,此时存放的数据放于链表中,位于链表首部     

这就是Map集合特有的key必须不同,value可以相同

扩容:--------->当添加的数据达到临界值时(=数组的长度1*加载因子),时进行扩容,默认扩容为2倍

jdk8:数组+单向链表+红黑树

  1. 当使用空参构造器,创建对象时,底层没有创建长度为16的数组
  2. 当我们首次使用put()添加数据时,底层会创建长度为16的数组
  3. 底层创建的数组是Node[ ]
  4. 当某个索引位置的链表长度>8,且数组长度>64时,将此索引位置上的元素,使用红黑树存储
  5. 形成链表时,新添加到元素放在链表结尾

HashMap的常用方法:

    @Test
    public void test() {
        Map map =new HashMap<>();
        Map map1=new TreeMap<>();
    
        //增,put()
        map.put("aa", 98);
        map.put("bb", 948);
        map.put("vv", 938);
        map.put("dd", 928);
        map.put("gg", 918);
        System.out.println(map);
        //改put()
        map.put("aa", 111);
        System.out.println(map);
        //删remove()
        map.remove("gg");
        System.out.println(map);
        //查get()
        System.out.println(map.get("aa"));
            
    }
    @Test
    public void test1() {
        Map map =new HashMap<>();
        //增,put()
        map.put("aa", 98);
        map.put("bb", 948);
        map.put("vv", 938);
        map.put("dd", 928);
        map.put("gg", 918);
        
        //返回所有的key构成的Set集合
        Set keySET=map.keySet();
        System.out.println(keySET);
            //遍历key构成的Set集合
        Iterator it=keySET.iterator();
        for (Object object : keySET) {
            System.out.println(object);
        }
                
        //返回所有value构成的Collection集合
        Collection c=map.values();
        //遍历values构成的Collection集合
        Iterator it1=c.iterator();
        while (it1.hasNext()) {
            System.out.println(it1.next());
            
        }
        
        //返回键值对构成的Set集合
        Set s=map.entrySet();
        Iterator it2=s.iterator();
        for (int i = 0; i < s.size(); i++) {
            System.out.println(it2.next());
        }
    }

 TreeMap:指定排序方式,添加的数据必须是同一个类创建的对象,必须重写Equals()方法和hashCode()方法

posted @ 2020-03-02 17:18  我的二天  阅读(219)  评论(0编辑  收藏  举报