java中的集合

物理结构:java

  • 顺序存储结构
  • 链式存储结构

逻辑结构算法

  • 线性结构:通常线性表、栈、队列、字符串、数组、广义表
  • 非线性结构:树、图

一、集合命名规则数组

  • 命名大致上能够归类为AbEf的形式: Ab表明物理结构,Ef表明逻辑结构
  • 如ArrayList,就是用数组实现线性表
  • LinkedList就是用链表实现的线性表

二、native方法:安全

  • arraycopy()@java.lang.System.class
  • 将src中的srcPos~srcPos+length-1的数据复制到dest中的destPos~destPos+length-1位置处 ​
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

三、顺序存储结构:ui

(1)线性表&栈线程

ArrayList:指针

  • 内部存储了一个Object[]
  • 提供随机访问
  • ArrayList中数据的移动大可能是利用System.arraycopy()方法实现,该方法是native方法;
  • 扩容;
    • 默认大小是10;
    • 最大容量Integer.MAX_VALUE - 8;
    • 扩容触发条件:当前要求容量大小大于当前容量大小
    • 正常扩容newCapacity = oldCapacity + (oldCapacity >> 1);
    • 使用System.arraycopy将数据所有移动到新的数组中
  • 缩容:手动调用trimToSize()方法,会缩到当前数组实际存储的数据大小

Vector:code

  • Vector与ArrayList共同点
    • 二者实现的功能相同,方法的实现也基本一致;
    • 都具备SubList内部类和Itr迭代器内部类
    • 都可以扩容和缩容
  • Vector与ArrayList区别:
    • 线程安全:Vector对大部分的方法使用了关键字Synchronized声明
    • 额外的%element%方法:这些方法会被Stack类所使用;

Stack:对象

  • Stack主要使用的是Vector<E>的方法进行具体的实现,自身没有状态量
  • 线程安全:继承Vector,故也是线程安全的
  • pop方法:使用elementAt+removeElementAt
  • push方法:使用addElement
  • search方法:从后往前搜索调用lastIndexOf

(2)队列继承

ArrayDeque:

  • 存储有一个Obejct[]数组;数组长度必须是2的幂次,由于这样就方便取余运算;
  • 有一个head和tail指针;
  • tail =(tail+1)&(elements.length-1)
  • head =(head+1)&(elements.length-1)
  • size = (tail-head)&(elements.length-1)
  • 扩容:
    • 正常扩容后大小为原数组长度2倍
    • 利用System.arraycopy方法实现

PriorityQueue:

  • 类中存储有一个Object[]数组
  • size为当前数组中存储的数据的大小
  • 存入的数据类型要求实现了Comparable接口
  • 数据的添加和删除操做伴随着调堆的操做;
  • 具备扩容功能:
    • 扩容大小:当前大小的2倍或者1.5倍
    • 扩容条件:准备存入的数据量大于当前Obejct数组的长度;

(3)Map

HashMap:

  • 内部存储了一个Node<K,V>[] table;
  • 内部有定义一个Node内部类和TreeNode内部类
  • 后者是一颗红黑树
  • 数组的下标(散列值)等于hash(key)&n-1
  • 会自动扩容:
    • 默认大小是16;大小必须为2的幂
    • 最大容量是1<<30
    • 填装因子为0.75
    • 扩容触发条件:一旦当前存储数据大于门限(容量*填装因子)
    • 正常扩容newCapacity = oldCapacity<<1
    • 每一个桶中的数据分红两拨一波继续留在原散列值下面
    • 另外一波移动到原散列值+oldCapacity位置处
  • 不能自动减容
  • 红黑树的利用:
    • 桶中的元素大于某个固定值,则将该桶中的数据由链表存储结构,转换成红黑树存储结构
    • 在此以后的全部操做交由红黑树进行处理
    • 在扩容的时候,对红黑树进行拆分的过程当中
    • 若是最后元素个数小于固定值,则将红黑树存储结构转换为普通链表存储结构

HashTable:

  • 基本与HashMap相似;
  • 线程安全:HashTable的大部分方法使用了Synchronized关键字进行标记
  • 没有红黑树:HashTable对桶中数据的存储没有使用红黑树,所以效率相对于hashmap会差一点
  • 不支持存储null:会抛出异常

HashSet:

  • 内部存储了一个HashMap<E,Object>变量
  • 一个简单版本的HashMap
  • 只使用了key而没有使用value部分,value永远存的都是固定的Object

(4)String

String

  • 内部存储的是一个final char[]字符数组;
  • 所以不能修改它指向的字符数组

StringBuidler

  • 内部存储的是一个char[]字符数组
  • 所以能够修改里面的字符
  • 对于数组的拷贝大多依赖于System.arraycopy的方法
  • 扩容
    • 默认大小为16
    • 容量最大值:Integer.MAX_VALUE
    • 正常状况扩容大小:int newCapacity = value.length * 2 + 2;
    • 扩容触发条件:准备存储的字符数大于当前数组的长度
  • 缩容:
    • 为当前存储数据的大小

StringBuffer

  • 与Stringbuilder相似
  • 线程安全:方法大多使用了Synchronized关键字标记

四、链式存储结构

TreeMap:

  • 定义了一个内部类Entry<K,V>
  • 该节点定义了这课红黑树的存储结构
  • 存储有该树的根节点
  • 要删除这颗树只须要将root指向null便可
  • GC以后便会回收该红黑树,形成其它节点的引用不可达
  • 每次插入、删除一个树中节点时
  • 都须要对这颗红黑树进行必定的调整

TreeSet:

  • 内部存储了一个TreeSet<E,Object>对象
  • 一个简单版本的TreeMap
  • 只使用了key而没有使用value部分,value永远存的都是固定的Object

LinkedList:

  • 内部存储一个双向链表
  • 全部的操做都是对该链表进行操做 

LinkedHashMap:

  • 数据存储是HashMap只是有在其上面加了一个链表结构
  • 每次对该HashMap中的数访问一次都会改变链表结构
  • 保证链表中的最后面的数据是最近刚被访问的那个节点的数据
  • 具备LRU算法特性(Least recently used,最近最少使用)
相关文章
相关标签/搜索