zoukankan      html  css  js  c++  java
  • java集合知识点

    若不重写equals方法,则调用的是object对象的equals方法,相当于==比较,比较的是对象的内存地址

    |------Collection接口:单列集合,用来存储一个一个对象

      |------List接口:存储有序的,可重复的数据,动态“数组”

        |------ArrayList:作为List接口下的主要实现类,线程不安全,效率高,使用Object[]存储数据

        |------LinkedList:底层使用双向链表存储,对于频繁插入和删除操作,使用效率比ArrayList高,链表中的元素只影响前一个和后一个元素,当插入元素时,修改前一个元素和后一个元素指向新元素的指针,不需要全部数据进行移动

        |------Vector:作为List接口古老的实现类,线程安全,效率低,使用Object[]存储数据

      |------Set接口:存储无序的,不能重复的数据

        |------HashSet:作为Set接口的主要实现类,线程不安全,可以存储null值

          |------LinkedHashSet:作为HashSet的子类,遍历其内部数据时,可以按照添加的顺序去遍历

        |------TreeSet:可以按照添加的对象,指定属性进行排序

    jdk1.7 ArrayList中原理是,构造的时候直接初始化一个长度为10的数组,若后期数据增量超过10,则就进行1.5倍长度的扩容

    jdk1.8 ArrayList中原理是,构造的时候不初始化数组,而是在调用集合方法add的时候,进行默认长度为10的数组创建,若增量超过10,则进行1.5倍长度扩容

    vector中原理是,底层创建长度为10的数组,扩容方式是原数组的2倍

    无序性:不等于随机性,并不按照添加的顺序添加数据,而是根据数据的hash值决定数据的添加的位置

    不可重复性:使用equals进行元素判断,相同的元素不能添加进来

    添加元素的过程:已HashSet为例:

    我们向HashSet中添加元素a,首先调用a所在类的hashCode()方法,计算元素a的哈希值,此哈希值通过某种算法计算出在hashSet底层数组中的存放位置(即为:索引位置),判断此位置上是否有其他元素,如果此位置上没有元素,则a元素添加成功,如果此位置上有其他元素b(或已链表形式存在的多个元素),则比较元素a和元素b的哈希值,如果哈希值不相同,则元素a添加成功,如果哈希值相同,进而需要调用元素a的所在类的equals方法:若方法返回true,表明元素a与存在元素重复,添加失败,若返回false,说明跟现有元素存在差异,则添加成功。 

    对于添加成功的情况2和情况3而言,元素a与已经存在指定索引位置上数据以链表的方式存储数据

    jdk7:元素a放到数据中,指向原来数组中的元素

    jdk8:原来的元素在数组中,指向a,  7上8下

    HashSet底层:数组+链表

    要求:向Set中添加数据的类,必须重写hashCode()和equals()方法,以实现对象相等规则,相等的对象必须具有相等的散列值(哈希值)

    LinkedHashSet:作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,用来记录前一个数据和后一个数据。不要理解成LinkedHashSet有序。

    优点:对于频繁的遍历操作,使用LinkedHashSet的效率更高

    TreeSet:向其中加入对象,必须是相同类型的

    自然排序:TreeSet中的对象必须实现Comparable接口,实现CompareTo方法,若调用CompareTo方法返回的是0,则代表2个对象相等,不继续添加到set集合中,不使用equals了

    定制排序:在初始化TreeSet集合对象的时候,传递一个Comparator接口的实现对象。定制一个比较规则,使用compare方法进行比较,不使用equals了

    |------Map:双列数据,存储key-value数据,

      |------HashMap:作为Map接口的主要实现类,线程不安全,效率高,可存储null的key和value

        |------LinkedHashMap:保证在遍历map对象时,可以按照添加的顺序进行遍历,原理是在原有HashMap基础上,添加了一对指针,用来指向前一个和后一个对象。

      |------TreeMap:保证按照添加的key-value对 进行排序,按照key进行排序(自然排序或定制排序),底层属于红黑树

      |------HashTable:作为古老的Map接口实现类:线程安全,效率低,不能存储null的key和value

        |------Properties:常用来处理配置文件。key和value都是String类型

    HaskMap的底层:数组+链表(jdk7之前)

            数组+链表+红黑树(jdk8)

    Map结构的理解:

      Map中的key:无序的、不可重复的,使用Set集合储存   ---》key所在的类要重写hashCode()和equals()(以HashMap为例)

      Map中的value:无序的、可重复的,使用Collection存储所有的value ---》value所在类需要重写equals()

      一个key-value对,组成一个Entry对象

      Map中的Entry:无序的,不可重复的,使用set存储所有的Entry

    HashMap的底层实现原理:以jdk7为例说明

      HashMap hashMap = new HashMap();

      在实例化以后,底层创建了一个长度是16的一维数组,类型是Entry[] table。

      。。。可能已经执行过多次put。。。

      map.put(key1,value1)

      首先计算key1所在类的hashCode(),计算哈希值,此哈希值经过某种算法计算以后,得到在Entry数组中的存放位置。

      如果此位置上没有数据,此时key1-value1的数据添加成功  ---情况1

      如果此位置上的数据不为空,意味着此位置上存在一个或多个数据(以链表形式存在),比较当前key1和已经存在的一个或多个数据的哈希值,

        如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1添加成功。---情况2

        如果key1的哈希值与已经存在的数据的哈希值相同,则调用key1所在类的equals方法,

          如果equals返回false,key1-value1添加成功

          如果equals返回true,使用value1去替换相同key1的value值

      在不断添加的过程中,默认的扩容方式是原有数据量的2倍(超出临界值,并且该插入的位置不为空),并将原有数据提取过来

      

      jdk8:相较于jdk7中底层的不同

      1.底层没有创建一个长度为16的Entry数组

      2.jdk8底层的数组,是Node[],而非Entry[]

      3.首次调用put方法时,底层去创建长度为16的Node[]

      4.jdk7中的底层结构:数组+链表,jdk8中的底层结构:数组+链表+红黑树。当数组中的某一个索引位置上的元素,以链表形式存在的数据个数大于8,且当前数组的长度超过64,此时此索引位置上的索引数据改为使用红黑树存储。

      HashMap初始容量:16

      加载因子:0.75

      扩容临界值:初始容量*加载因子 = 12

      

  • 相关阅读:
    Educational Codeforces Round 10 C. Foe Pairs 水题
    Educational Codeforces Round 10 B. z-sort 构造
    CDOJ 1048 Bob's vector 三分
    Educational Codeforces Round 10 A. Gabriel and Caterpillar 模拟
    第14届电子科大初赛民间盗版部分题目题解
    HDU 5654 xiaoxin and his watermelon candy 离线树状数组 区间不同数的个数
    HDU 5653 Bomber Man wants to bomb an Array. dp
    HDU 5652 India and China Origins 二分+并查集
    HDU 5651 xiaoxin juju needs help 数学
    HDU 5650 so easy 数学
  • 原文地址:https://www.cnblogs.com/zst-blogs/p/10860600.html
Copyright © 2011-2022 走看看