集合之Map、Collections

Map<K,V>

Map接口实现类的特点

  1. Map接口无序;

  2. Map用于保存具有单向一对一映射关系的数据:key-value(双列结构);键值对

  3. Map中的键和值只能是引用类型;

  4. Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中;

  5. Map中的key不可以重复;原因和HashSet一样,分析源码(key相同,等价于替换)

  6. Map中的value可以重复;

  7. Map中的key和value均可为null,但key只能有一个;因为不可重复

  8. 常用String类作为Map的key;

  9. 双列数据结构的顶级父类

Map的底层机制

0531韩顺平Java_Map接口特点2哔哩哔哩_bilibili

Map常用方法

  • put:添加、替换

  • remove:根据键值删除映射关系、删除指定的k-v映射

  • get:根据键值获取value

  • size:获取元素个数

  • inEmpty:判断个数是否为0,空位true,反之false

  • clear:清空

  • containsKey:查找键是否存在

Map的遍历元素方式

  • 通过键集合遍历:keySet()获取所有的键;返回一个存储所有的k的Set集合,使用增强for、迭代器遍历,通过每个k取出对应的v;

  • 通过值集合遍历:values()获取所有的值;返回一个存储所有的value的Collection集合,可以通过迭代器、增强for遍历;

  • 键值映射集合:entrySet()获取所有关系k-v;返回一个存储所有k-v的Set集合,使用迭代器、增强for取出每个k-v对象,从而得到键、值;注意:Set集合中默认Object类型,取出的元素无法得到键、值;可以在取出k-v时利用泛型指定set存储Map.Entry类型的元素,或者在遍历中把每个k-v强转为Map.Entry

Map总结

  1. Map接口的常用实现类:HashMap、Hashtable和Properties;

  2. HashMap是Map接口使用频率最高的实现类;

  3. HashMap是以key-value键值对的方式来存储数据;

  4. key不能重复,但值可以重复,允许null键和null值;

  5. 如果添加相同的key,原来对应的value会被覆盖,等同于修改;

  6. 与HashSet一样,是无序的;因为底层是以hash表的方式来存储的

  7. HashMap没有实现同步,因此线程不安全;

  • 构造方法

空参构造,默认初始容量16,默认负载因子0.75

指定初始容量的有参构造

  • 增删改查

    增:put

    删:remove;删除指定K对应的值,返回删除的值;删除指定K对应指定V的键值对,不存在或不对应返回false;

    改:replace、put、

    查:get;K值存在返回对应的值,不存在返回null;

HashMap

  • HashMap();空参构造,默认初始容量16,默认负载因子0.75

  • 元素无序

  1. (k,v)是一个Node实现了Map.Entry<K,V>,查看HashMap的源码可以看到

  2. jdk7.0的hashmap底层实现[数组+链表],jdk8.0底层[数组+链表+红黑树]


HashMap底层机制:

  1. HashMap底层维护了Node类型的数字table,默认为null;

  2. 默认负载因子0.75;

  3. 当添加key-value时,通过key的哈希值得到在table的索引,然后判断该索引是否有元素,如果没有元素直接添加。如果有元素,继续判断该元素的key和准备添加的key是否相等,如果相等,直接替换对应的val;如果不相等,需要判断是树结构还是链表结构,做出相应处理。如果添加时发现容量不够,则需要扩容。

  4. 第一次添加,table扩容为16,临界值为12;(16的0.75倍);

  5. 后续扩容,为原来容量的2倍,临界值为原来临界值的2倍;

  6. 在Java 8中,如果一个链表的元素个数到达 TREEIFY_THRESHOLD(默认是8),并且table的大小>=MIN_TREEIFY_CAPACITY(默认64),就会进行树化(红黑树);树化后,提高检索效率

0537韩顺平Java_HMap源码解读哔哩哔哩_bilibili

HashMap扩容树化触发

0538韩顺平Java_HMap扩容树化触发哔哩哔哩_bilibili

LinkedHashMap

  • 特点:

    1. 它是HashMap的子类,继承了其特性

    2. 底层采用的是哈希表+链表结构,能够包装存入的元素是有序的

    3. 允许null值存在

    4. 需要进行容器初始化

    5. 需要动态扩容

Hashtable

基本介绍

  1. 存放的元素是键值对:k-v

  2. Hashtable的键和值都不能为null;否则会抛出空指针异常;

  3. Hashtable使用方法和HashMap基本一样;

  4. Hashtable是线程安全的(synchronized),HashMap线程不安全的;

Hashtable底层机制

  1. 底层有一个数组Hashtable$Entry[], 初始化大小为11;

  2. 初始临界值 threshold 8 = 11 * 0.75;扩容后,临界值 = 新容量*0.75,取整

  3. 扩容:当count >= threshold时,就进行扩容,新容量 = 老容量*2+1;

0540韩顺平Java_Hashtable扩容哔哩哔哩_bilibili

 版本线程安全(同步)效率允许null键和null值
HashMap 1.2 不安全 可以
Hashtable 1.0 安全 较低 不可以

Properties

基本介绍

  1. Properties类继承自Hashtable类并且实现了Map接口,也是一种键值对的形式来保存数据;

  2. 使用特点和Hashtable类似,键和值都不能为空,无序

  3. Properties还可以用于从xxx.properties文件中,加载数据到Properties类对象,并进行读取和修改

  4. 说明:工作中,xxx.properties文件通常作为配置文件,这个知识点在IO流中体现;

常用方法

  • get(k);通过k键获取v值

  • remove(k);通过k键删除键值对

  • put(k,v);通过k键修改v值

集合实现类的选择

根据业务操作特点,结合集合实现类的特性进行选择:

  • 先判断存储的类型:一组对象[单列]或一组键值对[双列]

  • 一组对象[单列]:选择Collection接口的实现子类

    • 允许重复:List

      • 增删多:LinkedList [底层维护了一个双向链表]

      • 改查多:ArrayList [底层维护了Object类型的可变数组]

    • 不允许重复:Set

      • 无序:HashSet,[底层是HashMap,维护了一个哈希表,即(数组+链表+红黑树)]

      • 排序:TreeSet

      • 插入与取出顺序一致:LinkedHashSet,维护了数组+双向链表;

  • 一组键值对[双列]:Map的实现子类

    • 键无序:HashMap,[底层是哈希表,即jdk7:数组+链表,jdk8:数组+链表+红黑树]

    • 键排序:TreeMap

    • 键插入与取出顺序一致:LinkedHashMap,

    • 读取文件:Properties

TreeSet与TreeMap

TreeSet

  • 实现了Set接口、SortedSet接口(保证集合带有排序特性);

  • TreeSet的底层还是TreeMap;

  • 默认输出顺序遵循字典排序;英文符号>数字>大写字母>小写字母>中文>中文符号;

  • 存储元素为自定义类,必须实现comparable接口,重写compare方法;

  • TreeSet的一个构造器可以传入一个比较器compare(匿名内部类),并指定排序规则;

    • 构造器把传入的比较器对象,赋给了TreeSet的底层TreeMap的属性this.comparator;

    • 调用add()方法添加时,同样会调用比较器,添加重复元素则添加失败;

0543韩顺平Java_TreeSet源码解读哔哩哔哩_bilibili

TreeSet treeSet = new TreeSet(new Comparator(){
           @Override
           public int compare(Object o1, Object o2) {
               //调用String的compareTo的方法进行字符串大小比较
               //可以通过调换(String)o1与(String)o2,进行反序排列
               //return ((String)o1).compareTo((String)o2);//按字符串顺序比较
               return ((String)o1).length() - ((String)o2).length();//按字符串长度比较
          }
      });

TreeMap

  • 实现了Map、SortedMap接口,带有排序的特性;

  • 底层结构是红黑树;

  • 不需要容器初始化,不需要扩容;

  • 不允许存放null键和null值;

0544韩顺平Java_TreeMap源码解读哔哩哔哩_bilibili

Collections工具类

工具类介绍

  1. Collections是一个操作Set、List和Map等集合的工具类;

  2. Collections中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作;

  • 排序操作(部分,类图中可查看全部)(均为static方法)

    1. reverse(List):反转List中元素的顺序

    2. shuffle(List):对List集合元素进行随机排序//可用于抽奖打乱

    3. sort(List):根据元素的自然顺序对List集合元素进行升序排序

    4. sort(List,Comparator):根据指定的Comparator产生的顺序对List集合元素进行排序

    5. swap(List,int i,int j):将List集合中的i处元素和j处元素进行交换;j不能集合索引越界

重写compare方法,运用sort方法对集合进行指定规则排序

Collections.sort(list, new Comparator() {//按字符串长度升序排序
           @Override
           public int compare(Object o1, Object o2) {
               if (o1 instanceof String && o2 instanceof String){
                   return ((String)o1).length()-((String)o2).length();
              }else return 0;
          }
      });
  • 查找、替换(部分)

    1. Object max(Collection):根据元素的自然顺序,返回集合中最大元素;

    2. Object max(Collection,Comparator):根据Comparator指定规则返回集合中最大的元素;

    3. Object min(Collection):最小元素;

    4. Object min(Collection , Comparator):返回指定规则排序后的最小元素;

    5. int frequency(Collection , Object):返回集合中指定元素出现的次数是;

    6. void copy (List dest , List scr):将scr中的内容复制到dest中;

      • 为了完整复制scr,需要先给dest赋值,大小和scr.size()一样,否则会报索引越界异常

        for(int i = 0;i < scr.size(); i++){

        dest.add("")}

    7. boolean replaceAll(List list,Object oldVal , Object newVal):使用newVal替换List对象所有oldVal;

posted @ 2022-08-19 09:45  大嘟肚  阅读(49)  评论(0)    收藏  举报