• JAVA容器全面总结


    1      容器体系图

    简图:

       

    详图:

    2      基础

    2.1      Iterator接口

    迭代器。

    具有的能力:后向迭代、删除。

    2.2      Iterable接口

    表示一个类具有迭代能力。

    提供能力:通过iterator()方法,返回iterator。

    2.3      Collection接口

    集合接口

    继承Iterable,具有迭代能力

    新增接口:

           Size,isEmpty,contains,toArray,add,remove,以及批量操作,条件操作。

    2.4      AbstractCollection抽象类

    这不是接口了,是个抽象类,实现了Collection接口

    实现了Collection种的大部分方法。

    toArray,这个的实现是新new的一个数组,把元素一个个拷贝上去。

    2.5      Collection的重要子接口

    List、Set、Queue

    3      工具类

    3.1      Array类

    这个类属于java.lang.reflect包,所以可以看出,用的是反射的方法。

    然后,这是个final类,不可以new,只是提供static方法。

    The {@code Array} class provides static methods to dynamically create and access Java arrays.

    提供静态方法,创建和访问java数组。

    提供方法:

    NewInstance, getLength,get,getXXX类型,set,setXXX类型,

    3.2      Collections类

    容器工具类

    方法见:https://blog.csdn.net/u013256816/article/details/50924875

    1. 调用一个空List,Set,Map  //静态成员变量
    2. addAll
    3. binarySearch  利用二分法在指定的集合中查找元素
    4. sort
    5. shuffle  //混排。混排算法所做的正好与sort相反:它打乱在一个List中可能有的任何排列的踪迹。
    6. reverse  //反转
    7. synchronizedXXX //确保所封装的集合线程安全(强同步)
    8. unmodifiableXXXX //确保所封装的集合不能修改。

    4      List

    4.1      特征

    特征:有顺序可以重复,有顺序所以操作时可以在方法中加入索引参数。

    同样继承于Collection的Set则不可排序。

    虽然我们一般都用iterator单向遍历list,但List是都是可以用ListIterator迭代器双向迭代的。

    4.2      ListIterator

    继承自Iterator

    增加功能:

    前向迭代类的:previous,

    索引类:nextIndex,previousIndex

    操作类:增加、修改

    4.3      List接口

    继承自Collection

    增加功能:

    获取对应的迭代器:listIterator

    基于索引/可排序的功能:sort,indexOf,lastIndexOf,subList

    4.4      AbstractList抽象类

    继承自AbstractCollection

    实现List接口

    实现了迭代器。

    4.4.1        Itr内部类

    AbstractList可返回的迭代器。

    实现了Iterator,通过int cursor记录迭代位置。

    4.4.2        ListItr内部类

    AbstractList可返回的迭代器。

    继承Itr

    增加功能:前向迭代、查看序号、增加、修改。

    4.4.3        SubList内部类

    AbstractList的内部类,用于计算sublist

    算出的sublist的元素与原list共用,只是在使用的时候加了个offset。

    4.5      AbstractList的三个重要子类

    ArrayList 数组实现的

    Vector 也是数组实现的,线程安全的

    LinkedList 链表实现的

    4.6      ArrayList类

    继承自AbstractList

    特征:用数组实现。

    实现:List、RandomAccess、Cloneable、Serializable

    数据存放:transient Object[] elementData;(transient不序列化)

    增加能力:

           自动扩容

    覆盖了AbstractList的三个内部类。是用数组的方式实现的迭代。

    4.7      Vector类

    基本同ArrayList

    数据存放:protected Object[] elementData;  --  这个没有用transient

    新特性:线程同步,大多数方法都用synchronized修饰了。

    4.8      AbstractSequentialList抽象类

    继承自AbstractList

    实现了一些接口,实现都是依赖于迭代器,但迭代器还是抽象的。

    4.9      Queue接口

    继承自Collection

    特征:先进先出队列

    提供接口:offer,poll,remove,element,peek

    4.10   Deque接口

    继承自Queue

    特征:双向列表

    提供接口:在Queue的基础上,添加上从头增删,从尾增删的接口。xxxFirst,xxxxLast.

    4.11   LinkedList

    继承自AbstractSequentialList
    实现:List、Deque、Cloneable、Serializable
    可以看到,跟ArrayList的区别是实现了Deque,没实现RandomAccess

    特征:双向链表实现的。

    新增接口:封装了Depue的一些双向列表的一些接口,如 push,pop等

    覆盖了AbstractList的内部类ListItr,直接继承自ListIterator。用列表的方式实现迭代。

    用途:堆栈、队列、双向列表。

    4.12   Stack类

    继承自Vector

    封装Vector方法实现栈接口:push pop peek

    5      Set

    5.1      特征

    无顺序不可以重复

    无序因而不能通过索引操作对象

    5.2      Set接口

    继承自Collection

    没提供新的接口,只是声明这是一个Set类型的Collection

    5.3      AbstractSet抽象类

    继承自AbstractCollection

    实现Set接口

    5.4      HashSet类

    继承自AbstractSet

    实现Set, Cloneable, Serializable

    数据结构:private transient HashMap<E,Object> map;

    此处可见,HashSet是用HashMap实现的,只是用key存放实际对象,用Vaule存放了一个空的常量。private static final Object PRESENT = new Object();

    Iterator是返回key的Iterator。

    5.5      LinkedHashSet类

    继承自HashSet

    实现Set, Cloneable, Serializable

    跟HashSet的区别是他是用LinkedHashMap来存放数据的,也就是说,区别就是HashMap和LinkedHashMap的区别。

    5.6      SortedSet接口

    继承自Set接口

    添加了顺序功能接口:

           位置:First,last

    子Set:subSet,headSet,tailSet

    需要一个比较运算。

    5.7      NavigableSet接口

    继承自SortedSet

    添加了导航功能(返回和给定元素有响应关系的元素):

           Lower,floor,ceiling,higher,pollFirst,pollLast

    5.8      TreeSet类

    继承自AbstractSet

    实现NavigableSet,Cloneable,Serializable

    数据对象:private transient NavigableMap<E,Object> m;

    具有排序功能

    功能还是依赖于对应的map类。

    6      Map

    6.1      Map体系图

     

    6.2      特征

    6.3      Map接口

    并没有继承自Collection,也没有声明iterable,仅仅是声明了一些和Collection类似的方法。

    基础方法:Size、isEmpty…

    Key相关方法:containsKey、containsValue…

    元素操作:get、put、remove…

    Collection<V> values();

    Set<Map.Entry<K, V>> entrySet();

    6.4      AbstractMap抽象类

    继承自Map

    6.5      HashMap类

        extends AbstractMap<K,V>

    implements Map<K,V>, Cloneable, Serializable

    存数据的地方:transient Node<K,V>[] table;  //这里数组的每个Node代表一个桶。

           static class Node<K,V> implements Map.Entry<K,V>//node中存放了next node的地址。

    实际数据结构如下图:

     

    HashMap 永远都是在链表的表头添加新元素。

    6.5.1        自动扩容

    随着HashMap中元素的数量越来越多,发生碰撞的概率将越来越大,所产生的子链长度就会越来越长,这样势必会影响HashMap的存取速度。为了保证HashMap的效率,系统必须要在某个临界点进行扩容处理,该临界点就是HashMap中元素的数量在数值上等于threshold(table数组长度*加载因子)。但是,不得不说,扩容是一个非常耗时的过程,因为它需要重新计算这些元素在新table数组中的位置并进行复制处理。所以,如果我们能够提前预知HashMap 中元素的个数,那么在构造HashMap时预设元素的个数能够有效的提高HashMap的性能。

    6.5.2        HashMap 的底层数组长度为何总是2的n次方?

    对hash取余时,对2^n-1做与运算即可。

    这样可以保证最大的利用率和最小的碰撞机会。

    6.5.3        Fail-Fast 机制

    我们知道 java.util.HashMap 不是线程安全的,因此如果在使用迭代器的过程中有其他线程修改了 map,那么将抛出 ConcurrentModificationException,这就是所谓 fail-fast 策略。

    在迭代过程中,判断 modCount 跟 expectedModCount 是否相等,如果不相等就表示已经有其他线程修改了 Map:

    注意到 modCount 声明为 volatile,保证线程之间修改的可见性。

    6.6      LinkedHashMap类

    public class LinkedHashMap<K,V>
        extends HashMap<K,V>
        implements Map<K,V>

    LinkedHashMap继承了HashMap的所用特性,并且还通过额外维护一个双向链表保持了有序性

    对于每次put进来Entry,除了将其保存到哈希表中对应的位置上之外,还会将其插入到双向链表的尾部。

        static class Entry<K,V> extends HashMap.Node<K,V> {

            Entry<K,V> before, after; //节点在原先的基础上,加上了双向列表的属性。

    }

     

    LinkedHashMap重写了HashMap 的迭代器,它使用其维护的双向链表进行迭代输出。

    6.7      Hashtable类

    public class Hashtable<K,V>
        extends Dictionary<K,V>
        implements Map<K,V>, Cloneable, java.io.Serializable {

    Dictionary类是任何可将键映射到相应值的类(如 Hashtable)的抽象父类,每个键和值都是对象。但Dictionary 这个类过时了,新的实现类应该实现Map接口。

    HashTable和HashMap几乎功能是相同的,差别:

    1、  HashTable是同步的。

    2、  HashTable不允许Null做key。

    6.8      ConcurrentMap接口

    没干啥,只是声明为同步

    6.9      ConcurrentHashMap类

    public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
        implements ConcurrentMap<K,V>, Serializable {
    使用乐观锁(asTabAt)进行同步控制的。
    比HashTable(使用synchronized)性能要高的多。
     
     

    6.10   SortedMap接口

    public interface SortedMap<K,V> extends Map<K,V>

    比较、排序

    6.11   NavigableMap接口

    public interface NavigableMap<K,V> extends SortedMap<K,V> {

    添加了导航功能(返回和给定元素有响应关系的元素):

           Lower,floor,ceiling,higher,pollFirst,pollLast

    6.12   TreeMap类

    public class TreeMap<K,V>
        extends AbstractMap<K,V>
        implements NavigableMap<K,V>, Cloneable, java.io.Serializable

    TreeMap实现了红黑树的结构,形成了一颗二叉树。

    特征:

    1、  用红黑树实现了插入时的自然排序

    2、  红黑树的好处:平衡二叉树,查询效率高。

    7      Java1.8新特性

    7.1      Foreach

    7.2      Spliterator

    8      参考

    java容器类总结

    https://www.cnblogs.com/wishyouhappy/p/3669198.html

    Map 综述(一):彻头彻尾理解 HashMap

    https://blog.csdn.net/justloveyou_/article/details/62893086

    Map 综述(二):彻头彻尾理解 LinkedHashMap

    https://blog.csdn.net/justloveyou_/article/details/71713781

    Hashtable 的实现原理

    http://wiki.jikexueyuan.com/project/java-collection/hashtable.html

    Java集合--TreeMap完全解析

    https://www.jianshu.com/p/2dcff3634326

  • 相关阅读:
    MySQL数据库优化
    数据库优化
    shell使用ps -ef|grep xxx时不显示grep xxx进程的方法
    Linux:PS查看进程信息,和查看tomcat内存等信息
    neo4j在linux下的安装
    Markdown 语法整理大集合2017
    TOP 10开源的推荐系统简介
    Molecule – 帮助你构建跨平台的 HTML5 游戏
    精美照片在网页设计中的13个优秀应用案例
    开发中可能会用到的几个 jQuery 小提示和技巧
  • 原文地址:https://www.cnblogs.com/aoyihuashao/p/10645335.html
Copyright © 2020-2023  润新知