Java集合框架(四)—Map

一、Map

Map存储的是k-v键值对映射的数据

1、特点

      key-value映射

2、具体API操作

  •   增加:

     put(k,v):添加元素

Map<String,Integer> map = new HashMap<>();
map.put("a",1);
map.put("b",2);
map.put("c",3);
map.put("d",4);
System.out.println(map);
  •    查找:

     isEmpty:判断是否为空

     size:返回map的大小

     containsKey(k):

     containsValue(v)

     get(k)

System.out.println(map.get("a"));
System.out.println(map.containsKey("c"));
System.out.println(map.containsValue(1));
System.out.println(map.isEmpty());
System.out.println(map.size());
  •   删除:

    clear:清空集合中的所有元素

    remove:删除指定元素

map.remove("a");
System.out.println(map);
map.clear();//清空
System.out.println(map);

3、HashMap

  • 存储结构:数组+链表(jdk1.7)      数组+链表+红黑树(jdk1.8)
  • key无序,唯一(Set也具有唯一,无序的特点)

HashMap源码注意事项:

  • HashMap初始值为2的N次幂(Must be a power of two):

             1、方便进行&操作,提高效率,&要比取模运算效率要高

                          hash& (initCapacity-1)

             2、在扩容之后涉及到元素的迁移过程,迁移的时候只需要判断二进制的前一位是0或者是1即可,如果是0,表示新数组和旧数组的下标位置不变,如果是1,只需要将索引位置加上旧数组长度值即为新                       数组的下标

  • 加载因子(load factor):与扩容有关,初始容量是16,当16*0.75时进行扩容,并不是在达到初始容量16时扩容
  • jdk1.7源码知识点:  数组+链表

           1、默认初始容量

           2、加载因子

           3、put操作

                  -设置值,计算hash

                  - 扩容操作

                  -数据迁移的过程 transfer

  • jdk1.8源码知识点:  数组+链表+红黑树

         1、判断链表长度若是超过8则转为红黑树(TREEIFY_THRESHOLD=8),这个阈值根据泊松分布得出的,在源码中实际是长度达到7时就会转为红黑树

if ((e = p.next) == null) {
        p.next = newNode(hash, key, value, null);
        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                treeifyBin(tab, hash);
        break;
 }

HashMap 与HashTable的区别:

  • HashMap线程不安全,效率比较高;HashTable线程安全,效率低
  • HashMap中的key和value都可以为空,HashTable不允许为空

4、LinkedHashMap

存储结构:链表

有序的HashMap,速度快

TreeMap

存储结构:红黑树

有序,速度没有HashMap快

问题:Set与Map有关系吗?

采用了相同的数据结构,只是用于map的key存储数据。

5、遍历map

 

Map<String,Integer> map = new HashMap<>();
map.put("a",1);
map.put("b",2);
map.put("c",3);
map.put("d",4);
System.out.println(map);

 

  • 方法一
System.out.println("-------------遍历:根据key获取value----------------------");
//遍历 ,根据key获取值
Set<String> key = map.keySet();
for(String keys:key){
      System.out.println(keys+"="+map.get(keys));
}
  • 方法二
System.out.println("-------------遍历:获取value----------------------");
//只能获取对应的value值,不能根据value来获取key
Collection<Integer> values = map.values();
for(Integer i:values){
      System.out.println(i);
}
  • 方法三
System.out.println("-------------遍历:迭代器----------------------");
Set<String> key2 = map.keySet();
Iterator<String> iterator = key2.iterator();
while (iterator.hasNext()){
String keyIterator = iterator.next();
        System.out.println(keyIterator+"="+map.get(keyIterator));
}
  • 方法四

        Map.entry:表示的是K-V组合的一组映射关系,key和value成组出现

System.out.println("-------------遍历:entrySet()---------------------");
Set<Map.Entry<String, Integer>> entries = map.entrySet();
Iterator<Map.Entry<String, Integer>> iterator1 = entries.iterator();
while (iterator1.hasNext()){
     Map.Entry<String, Integer> next = iterator1.next();
     System.out.println(next.getKey()+"--"+next.getValue());
}

二、Collections工具类

Collections和Collection不同,前者是集合的操作类,后者是集合接口

Collections提供的静态方法: 

  • addAll():批量添加
  • sort():排序
  • binarySearch():二分查找(注意:二分查找的时候需要先进行排序操作,如果没有进行排序,是找不到指定元素的)
  • fill():替换(填充)
  • shuffle():随机排序
  • reverse():逆序
 List<String> list = new ArrayList<>();
//list集合添加元素的两种方式
list.add("ad");
list.add("fgc");

Collections.addAll(list,"r","opwgh","poprewq");

//默认根据字母表进行排序
Collections.sort(list);

//也可以自定义内部比较器,按字符串长度进行比较
 Collections.sort(list,new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                if(o1.length()>o2.length()){
                    return 1;
                }else if(o1.length()<o2.length()){
                    return -1;
                }else{
                    return 0;
                }
            }
});

//逆序
Collections.reverse(list);

 

posted @ 2020-12-04 15:21  豆小豆1314  阅读(124)  评论(0编辑  收藏  举报