java集合框架---Map接口总结(精简版)

5.Map接口:(HashMap(最常用),LinkedHashMap,Hashtable,TreeMap)
5.1.HashMap:继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口
5.1.1.根据键的HashCode值存储数据,根据键可以直接获取它的值;
5.1.2.具有很快的访问速度,遍历时,取得数据的顺序是完全随机的;
5.1.3.不支持线程的同步,线程不安全,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致
5.1.4.键和值都可以为null;
5.1.5.不允许键重复,值可以重复
(1)如果多个键重复,后面的将覆盖前面的,只保留最后一个键值对数据
(2)如果多个值重复,键唯一,将全部展示键值对数据
5.1.6.jdk1.7中为底层数组+链表实现
5.1.7.jdk1.8中改为底层数组+红黑树实现

1.代码示例:HashMap方法使用汇总
          HashMap<String, String> hashMap = new HashMap<>();
          hashMap.put("1", "西游记");//
          hashMap.put(null, "红楼梦");
          hashMap.put("2","西游记");
          hashMap.put("3",null);
          hashMap.put(null,null);
          输出结果:{null=null, 1=西游记, 2=西游记, 3=null, 4=null}//不会显示红楼梦(前面的被覆盖了)
          hashMap.clear();//作用是清空HashMap
          hashMap.containsKey("1")//作用是判断HashMap是否包含key,包含为true,否则为false
          hashMap.containsValue("西游记") //作用是判断HashMap是否包含value,包含为true,否则为false
          hashMap.entrySet()//作用是返回“HashMap中所有Entry(key-value)的集合”,它是一个集合
          System.out.println(hashMap)=System.out.println( hashMap.entrySet());
          输出结果:{null=null, 1=西游记, 2=西游记, 3=null, 4=null}
          hashMap.values()//作用是返回“HashMap中所有value的集合”,它是一个集合
          输出结果:[null, 西游记, 西游记, null, null]
          hashMap.keySet()//作用是返回“HashMap中所有key的集合”,它是一个集合
          输出结果:[null, 1,2,3]
          hashMap.get("1")//作用是获取key对应的value
           hashMap.remove("1")//作用是删除key=1的键值对
2。遍历:可以遍历key-value,key,value三种形式
      第一种:推荐(尤其量大时)
       HashMap<String, String> hashMap = new HashMap<>();
         for(Map.Entry<String, String> entry: hashMap .entrySet())
    {
     System.out.println("Key: "+ entry.getKey()+ " Value: "+entry.getValue());
    }
     第二种:显示调用map.entrySet()的集合迭代器
      Iterator<Map.Entry<String, String>> iterator=hashMap .entrySet().iterator();
       while(iterator.hasNext())
    {
     Map.Entry<String, String> entry=(Entry<String, String>)iterator.hasNext();
     System.out.println("Key: "+entry.getKey()+" Value: "+entry.getValue());
    }
    第三种:分别获取key,value
    for(String key:map.keySet())
    {
     System.out.println("Key: "+key+" Value: "+map.get(key));
    }
    第四种:获取value
     for(String v:map.values())
    {
     System.out.println("The value is "+v);
    }
  实际应用中前两种效率高!!!      

5.2.Hashtable:继承自Dictionary类
5.2.1.支持线程同步,即同一时刻只能有一个线程对hashtable进行操作(这导致了它的写入较慢)
5.2.2.不允许键或值为空
5.2.3.jdk1.7中为底层数组+链表实现
5.2.4.jdk1.8中改为底层数组+红黑树实现
5.3. LinkedHashMap:是HashMap的一个子类,用法和HashMap一样
5.3.1.当希望有顺序地去存储key-value时,就需要使用LinkedHashMap了(默认为插入顺序)

      插入时什么顺序,输出时就是什么顺序!
      代码示例:
      (1)使用HashMap
       HashMap<String, String> hashMap = new HashMap<>();
               hashMap.put("1", "西游记");
               hashMap.put("2", "红楼梦");
               hashMap.put("3", "水浒传");
         for(Map.Entry<String, String> entry: hashMap .entrySet())
    {
     System.out.println("Key: "+ entry.getKey()+ " Value: "+entry.getValue());
    }
       可能会输出:       Key:3  Value:水浒传
                         Key:1  Value:西游记
                         Key:2  Value:红楼梦
      (2)使用LinkedHashMap   
       LinkedHashMap   <String, String> linkedHashMap   = new LinkedHashMap   <>();
               linkedHashMap   .put("1", "西游记");
               linkedHashMap   .put("2", "红楼梦");
               linkedHashMap   .put("3", "水浒传");
         for(Map.Entry<String, String> entry: linkedHashMap   .entrySet())
    {
     System.out.println("Key: "+ entry.getKey()+ " Value: "+entry.getValue());
    }                 
        一定输出:        Key:1  Value:西游记
                         Key:2  Value:红楼梦
                         Key:3  Value:水浒传                  

5.4.TreeMap:继承于AbstractMap(了解)
5.4.1.通过红黑树实现的,本质是R-B Tree(红黑树),它包含几个重要的成员变量: root, size, comparator

      root:    (1) 是红黑数的根节点。它是Entry类型,Entry节点根据key进行排序,节点包含的内容为value
                (2)包含了红黑数的6个基本组成成分:key(键)、value(值)、left(左孩子)、right(右孩子)、parent(父节点)、color(颜色)
      size:是红黑数中节点的个数   
      comparator:Entry中的key比较大小是根据比较器comparator来进行判断的        

5.4.2.是非同步的
5.4.3.不允许key=null,允许value=null

代码示例:
 TreeMap<String, String> treeMap = new TreeMap<>();  
  treeMap.put("1", "西游记");
  treeMap.put("4", "红楼梦");
  treeMap.put("2",null);
  treeMap.put("3",null);
  //treeMap.put(null,null); 
  for(Entry<String, String> entry: treeMap .entrySet())
  {
   System.out.println("Key: "+ entry.getKey()+ " Value: "+entry.getValue());
  }
 输出:Key: 1 Value: 西游记
      Key: 2 Value: null
      Key: 3 Value: null
     Key: 4 Value: 红楼梦 

扩展:Map接口的同步实现

  (1)可以使用Hashtable实现类;
           1.采用的锁机制是一次锁住整个hash表,从而在同一时刻只能由一个线程对其进行操作
  (2)可以使用SynchronizedMap实现类      
  (3)可以使用java.util.concurrent包提供的ConcurrentHashMap  
           1.jdk1.7中采用了数组+Segment+分段锁的方式实现,线程安全
           2.jdk1.8中采用了数组+链表+红黑树的实现方式来设计,内部大量采用CAS操作
           2.通过把整个Map分为N个Segment,可以提供相同的线程安全,但是效率提升N倍,默认将hash表分为16个桶
           3.是使用了锁分段技术来保证线程安全的
           锁分段技术:首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,
                                其他段的数据也能被其他线程访问。 
           4.诸如get、put、remove等常用操作只锁住当前需要用到的桶。原来只能一个线程进入,现在却能同时有16个写线程执行,
              并发性能的提升是显而易见的                     

扩展:CAS是compare and swap的缩写,即我们所说的比较交换

 (1)cas是一种基于锁的操作,而且是乐观锁
        在java中锁分为乐观锁和悲观锁:
            悲观锁:是将资源锁住,等之前获得锁的线程释放锁之后,下一个线程才可以访问
            乐观锁:采取了一种宽泛的态度,通过某种方式不加锁来处理资源,性能较悲观锁有很大的提高
 (2)cas包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)
          如果内存地址里面的值V和预期原值A的值是一样的,那么就将内存里面的值更新成B

猜你喜欢

转载自blog.csdn.net/qq591009234/article/details/89376527