十一、Set系列集合、Map集合体系

Set系列集合、Map集合体系

Set系列集合

  • Set系列及系概述

    • Set系列集合特点

      • 无序:存取顺序不一致

      • 不重复:可以去重复

      • 无索引:没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取元素

    • Set集合实现类特点

      • HashSet:无序、不重复、无索引

      • LinkedHashSet:有序、不重复、无索引

      • TreeSet:排序、不重复、无索引

  • HashSet元素无序的底层原理:哈希表

    • HashSet集合底层采取哈希表存储的数据

    • 哈希表是一种对于增删改查数据性能都比较好的结构

    • 哈希表的组成

      • JDK8之前的,底层使用数组+链表组成

      • JDK8之后的,底层使用数组+链表+红黑树组成

    • 哈希值

      • 是JDK根据对象的地址,按照某种规则算出来的int类型的数值

    • Object类的API

      • public int hashCode(): 返回对象的哈希值

    • 对象哈希值的特点

      • 同一个对象多次调用hashCode()方法返回的哈希值是相同的

      • 默认情况下,不同对象的哈希值是不同的

  • HashSet元素去重复的底层原理

    • HashSet1.7版本原理解析:数组+链表+(结合哈希算法)

      • 创建一个默认长度16的数组,数组名table

      • 根据元素的哈希值数组的长度求余计算出应存入的位置(哈希算法)

      • 判断当前位置是否为null,如果是null直接存入

      • 如果位置不为null,表示有元素,则调用equals方法比较

      • 如果一样,则不存,如果不一样,则存入数组

        • JDK7新元素占老元素位置,指向老元素

        • JDK8中新元素挂在老元素下面

    • JDK8版本开始HashSet原理解析

      • 底层结构:哈希表(数组、链表、红黑树的结合体

      • 当挂在元素下面的数据过多时,查询性能降低,从JDK8开始后,链表长度超过8的时候,自动转换为红黑树

      • 结论:JDK8开始后,哈希表对于红黑树的引入进一步提高了操作数据的性能

    • 结论:如果希望Set集合认为2个内容一样的对象是重复的,必须重写对象的hashCode()和equals()方法

  • 实现类:LinkedHashSet

    • 集合概述和特点

      • 有序、不重复、无索引

      • 这里的有序指的是保证存储和取出的元素顺序一致

    • 原理:底层数据结构依然是哈希表,只是每个元素又额外的多了一个双链表的机制记录存储的顺序

  • 实现类:TreeSet

    • 集合概述和特点

      • 不重复、无索引、可排序

      • 可排序:按照元素的大小默认升序(由小到大)排序

      • TreeSet集合顶层是基于红黑树的数据结构实现排序的,增删改查性能都比较好

    • 注意:TreeSet集合是一定要排序的,可以将元素按照指定的规则进行排序。

    • TreeSet集合默认的规则

      • 对于数值类型:Integer,Double,官方默认按照大小进行升序排序

      • 对于字符串类型:默认按照首字符的编号升序排序。

      • 对于自定义类型如Student对象,TreeSet无法直接排序。

    • 结论:想要使用TreeSet存储自定义类型,需要制定排序规则

    • 自定义排序规则

      • TreeSet集合存储对象的时候有两种方式可以设计自定义比较规则

        • 方式一:让自定义的类(如学生类)实现Comparable接口重写里面的compareTo方法来制定比较规则

        • 方式二:TreeSet集合有参数构造器,可以设置Comparetor接口对应的比较器对象,来制定比较规则

    • 两种方式中,关于返回值的规则:

      • 如果认为第一个元素大于第二个元素返回正整数即可

      • 如果认为第一个元素小于第二个元素返回负整数即可

      • 如果认为第一个元素等于第二个元素返回0即可,此时TreeSet集合只会保留一个元素认为两者重复

    • 注意:如果TreeSet集合存储的对象有实现比较规则,集合也自带比较器,默认使用集合自带的比较器排序

Collection体系的特点、使用场景总结

  • 如果希望元素可以重复,又有索引,索引查询要快?

    • 用ArrayList集合,基于数组的(用的最多)

  • 如果希望原属可以重复,又有索引,增删首尾操作快?

    • 用LinkedList集合,基于链表

  • 如果希望增删改查都快,但是元素不重复、无序、无索引?

    • 用HashSet集合,基于哈希表的

  • 如果希望增删改查都快,但是元素不重复、有序、无索引

    • 用LinkedHashSet集合,基于哈希表和双链表

  • 如果要对对象进行排序

    • 用TreeSet集合,基于红黑树。后续也可以用List集合实现排序

补充知识:可变参数

  • 可变参数用在形参中可以接收多个数据

  • 可变参数的格式:数据类型…参数名称

  • 可变参数的作用:

    • 传输数据非常灵活,方便。可以不传输参数,可以传输1个或者多个,也可以传输一个数组

    • 可变参数在方法内部本质上就是一个数组

  • 可变参数注意事项

    • 一个形参列表中可变参数只能有一个

    • 可变参数必须放在形参列表的最后面

补充知识:集合工具类Collections

  • 作用:Collections并不属于集合,是用来操作集合的工具类

  • Collections常用的API

    • 方法名称说明
      public static <T> boolean addAll(Collection<? super T> c,T ... elements) 给集合对象批量添加元素
      public static void shuffle(List<?> list) 打乱List集合元素的顺序
  • Collections排序相关API

    • 使用范围:只能对于List集合的排序

    • 排序方式1:

      • 方法名称说明
        public static <T> void sort(List<T> list) 将集合元素按照默认规则排序
      • 注意:本方式不可以直接对自定义类型的List集合排序,除非自定义类型实现了比较规则Comparable接口

    • 排序方式2:

      • 方法名称说明
        public static <T> void sort(List<T> list,Comparator<? super T> c) 将集合中元素按照指定规则排序

         

Collection体系的综合案例

  • d_11 collectionstest

Map集合体系

  • Map集合的概述

    • Map集合是一种双列集合,每个元素包含两个数据

    • Map集合的每个元素的格式:key=value(键值对元素)

    • Map集合也被称之为“键值对集合”

    • Map集合整体格式:

      • Collection集合的格式:[元素1,元素2,元素3,……]

      • Map集合的完整格式:{key1=value1,key2=value2,key3=value3,……}

    • Map集合体系

      • Map

        • HashMap

          • LinkedHashMap

        • HashTable

          • Properties

        • ……

          • TreeMap

    • 使用最多的Map集合是HashMap

    • 重点掌握HashMap,LinkedHashMap,TreeMap

  • Map集合体系特点

    • Map集合的特点是由键决定的

    • Map集合的键是无序,不重复,无索引,值不做要求(可以重复)

    • Map集合后面重复的键对应的值会覆盖前面重复键的值

    • Map集合的键值对都可以为null

    • Map集合实现类特点

      • HashMap:元素按照键是无序,不重复,无索引,值不做要求(与Map体系一致)

      • LinkedHashMap:元素按照键是有序,不重复,无索引,值不做要求

      • TreeMap:元素按照键是排序,不重复,无索引的,值不做要求

  • Map集合常用API

    • Map是双列集合的祖宗接口,他的功能是全部双列集合都可以继承使用

    • Map API如下:

      • 方法名称说明
        V put(K key, V value) 添加元素
        V remove(Object key) 根据键删除键值对元素
        void clear() 移除所有的键值对元素
        boolean containsKey(Object key) 判断集合是否包含指定的键
        boolean containsValue(Object value) 判断集合是否包含指定的值
        boolean isEmpty() 判断集合是否为空
        int size() 集合的长度,也就是集合中键值对的个数

         

  • Map集合的遍历方式一:键找值

    • 先获取Map集合的全部键的Set集合

    • 遍历键的Set集合,然后通过键提取对应值

    • 键找值涉及到的API:

      • 方法名称说明
        Set<K> keySet() 获取所有键的集合
        V get(Object key) 根据键获取值
  • Map集合的遍历方式二:键值对

    • 先把Map集合转换成Set集合,Set集合中每个元素都是键值对实体类型了

    • 遍历Set集合,然后提取键以及提取值

    • 键值对涉及到的API:

      • 方法名称说明
        Set<Map.Entry<K,V>> entrySet() 获取索引键值对对象的集合
        K getKey() 获取键
        V getValue() 获取值
  • Map集合的遍历方式三:lambda表达式

    • 得益于JDK 8开始的新技术Lambda表达式,提供了一种更简单、更直接的遍历集合的方式

    • Map结合Lambda遍历的API

      • 方法名称说明
        default void forEach(BiConsumer<? super K,? super V> action) 结合Lambda遍历Map集合

         

  • Map集合的实现类HashMap

    • 特点:

      • HashMap是Map里面的一个实现类。特点都是由键决定的:无序、不重复、无索引

      • 没有额外需要学习的特有方法,直接使用Map集合里面的方法就可以了

      • HashMap跟HashSet底层原理是一模一样的,都是哈希表结构,只是HashMap的每个元素包含两个值而已

    • 实际上:Set系列集合的底层就是Map实现的,只是Set集合中的元素只要键数据,不要值数据而已

  • Map集合的实现类LinkedHashMap

    • 概述和特点

      • 由键决定:有序、不重复、无索引

      • 这里的有序指的是保证存储和取出的元素顺序一致

      • 原理:底层数据结构依然是哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序

  • Map集合的实现类TreeMap

    • 由键决定特性:不重复、无索引、可排序

    • 可排序:按照键数据的大小默认升序(由小到大)排序,只能对键排序

    • 注意:TreeMap集合是一定要排序的,可以默认排序,也可以将键按照指定的规则进行排序

    • TreeMap跟TreeSet底层原理是一样的

    • TreeMap集合自定义排序规则有2种

      • 类实现Comparable接口,重写比较规则

      • 集合自定义Comparator比较器对象,重写比较规则

补充知识:集合的嵌套

d_13 MapTest2

posted @ 2022-06-16 16:38  遨游JAVA的大叔  阅读(62)  评论(0)    收藏  举报