List Set Map简单理解

来源:互联网 发布:数据库升级策略 编辑:程序博客网 时间:2024/06/18 04:04

1、

public class ArrayList<E> extends AbstractList<E>        implements List<E>, RandomAccess, Cloneable, java.io.Serializable    private static final int DEFAULT_CAPACITY = 10;    private static final Object[] EMPTY_ELEMENTDATA = {};    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};    transient Object[] elementData; // non-private to simplify nested class access    private int size; 

实现了Collection接口
有序数组
内部使用数组存储,使用transient字段修饰,必须通过writeObject和readObject序列化和反序列化
可以存储null
可以转换成 Iterator,DescendingIterator(反的) 使用,如果换成 Iterator后,ArrayList 被其他线程修改,则使用Iterator操作会抛出ConcurrentModificationException
非线程安全
数组size不能满足添加子集时自动扩充,新增和删除时,数组要移位,因此查询和更新效率高,新增和删除效率低

2、

public class LinkedList<E>    extends AbstractSequentialList<E>    implements List<E>, Deque<E>, Cloneable, java.io.Serializable    transient int size = 0;    transient Node<E> first;    transient Node<E> last;

有序队列
内部使用链式存储,保存了前面和后面节点的地址,新增和删除时只需修改前驱和后继节点地址。查找需要遍历节点匹配。故增删效率较ArrayList高,查询效率较ArrayList低。
可以转换成 Iterator,DescendingIterator(反的) 使用,如果换成 Iterator后,LinkedList 被其他线程修改,则使用Iterator操作会抛出ConcurrentModificationException。
非线程安全
可以存储null
查询指定index元素时判断了是从开始节点查还是从结束节点查找,故遍历此时小于等于size/2
通过writeObject、readObject序列化和反序列化
peek只查第一个元素,没有返回null。
element只查第一个元素,没有抛出异常。
poll返回并且删除第一个元素,没有返回null
remove返回并且删除第一个元素,没有抛出异常
toArray转换成数组对象

3、

public class HashMap<K,V> extends AbstractMap<K,V>    implements Map<K,V>, Cloneable, Serializable {    static class Node<K,V> implements Map.Entry<K,V>        final int hash;        final K key;        V value;        Node<K,V> next;

参考网站:
https://zhuanlan.zhihu.com/p/21673805
http://www.importnew.com/20386.html
http://www.cnblogs.com/study-everyday/p/6373279.html
允许只有一个null键 和多个null值
非线程安全,多线程使用ConcurrentHashMap
桶+链+红黑色 模式,能够快速查找,增删改。
扩容是一个特别耗性能的操作,所以当程序员在使用HashMap的时候,估算map的大小,初始化的时候给一个大致的数值,避免map进行频繁的扩容。
如果一个对象作为Key,则还对象必须有equal()和hashCode()方法

(2) Hashtable:Hashtable是遗留类,很多映射的常用功能与HashMap类似,不同的是它承自Dictionary类,并且是线程安全的,任一时间只有一个线程能写Hashtable,
并发性不如ConcurrentHashMap,因为ConcurrentHashMap引入了分段锁。Hashtable不建议在新代码中使用,不需要线程安全的场合可以用HashMap替换,需要线程安全的场合可以用ConcurrentHashMap替换。

(3) LinkedHashMap:LinkedHashMap是HashMap的一个子类,保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的,也可以在构造时带参数,按照访问次序排序。

数组
数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找时间复杂度小,为O(1);数组的特点是:寻址容易,插入和删除困难;

链表
链表存储区间离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度很大,达O(N)。链表的特点是:寻址困难,插入和删除容易。

哈希表
那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提起的哈希表。哈希表((Hash table)既满足了数据的查找方便,同时不占用太多的内容空间,使用也十分方便。

4、

public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>    implements ConcurrentMap<K,V>, Serializable    transient volatile Node<K,V>[] table;    private transient volatile Node<K,V>[] nextTable;    private transient volatile long baseCount;    private transient volatile int sizeCtl;    private transient volatile int transferIndex;

参考网站:http://www.cnblogs.com/study-everyday/p/6430462.html
扩容参考网站:http://www.importnew.com/23907.html
key和value都不允许为null
JDK1.8的实现已经摒弃了Segment的概念,而是直接用Node数组+链表+红黑树的数据结构来实现,并发控制使用Synchronized和CAS来操作
初始化table时使用懒加载,只有在放入第一个元素后才会真正初始化table
只有计算hash结果相同才会出现阻塞,否则多线程之间相互不影响

5、

public class LinkedHashMap<K,V>    extends HashMap<K,V>    implements Map<K,V>    static class Entry<K,V> extends HashMap.Node<K,V> {        Entry<K,V> before, after;        Entry(int hash, K key, V value, Node<K,V> next) {            super(hash, key, value, next);        }    }    transient LinkedHashMap.Entry<K,V> head;    transient LinkedHashMap.Entry<K,V> tail;    //true 按访问顺序排序, false 按插入顺序排序(默认)    final boolean accessOrder;

accessOrder=false只有当插入值时才会将该结点放入尾结点,修改、查询不做任何处理
accessOrder=true 进行put/get/insert之后就算是对节点的访问,会把最近访问的放到最后,保证链表。
LinkedHashMap是Hash表和链表的实现,并且依靠着双向链表保证了迭代顺序是插入的顺序。
LinkedHashMap实现与HashMap的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可以是插入顺序或者是访问顺序。
使用场景:
a、扩展LinkedHashMap可以将最老的数据删除,如缓存场景扩展LinkedHashMap可以将最老的数据删除,如缓存场景
b、containsValue(o),如果o是经常被操作的的结点,则速度可能较HashMap快。

6、

public class HashSet<E>    extends AbstractSet<E>    implements Set<E>, Cloneable, java.io.Serializable    //直接通过map存储key     private transient HashMap<E,Object> map;     //map存储的value     private static final Object PRESENT = new Object();

只去重
非线程安全
允许null值
添加值得时候会先获取对象的hashCode方法,如果hashCode 方法返回的值一致,则再调用equals方法判断是否一致,如果不一致才add元素。
对于HashSet中保存的对象,请注意正确重写其equals和hashCode方法,以保证放入的对象的唯一性。
HashSet不能保存重复(通过equals和hashCode判断)对象,因为map的key是唯一的

7、

public class TreeSet<E> extends AbstractSet<E>    implements NavigableSet<E>, Cloneable, java.io.Serializable     public TreeSet() {        this(new TreeMap<E,Object>());    }

去重并且排序
E必须实现Comparable接口
使用TreeMap

8、

public class LinkedHashSet<E>      extends HashSet<E>      implements Set<E>, Cloneable, java.io.Serializable

继承了HashSet
内部使用LinkedHashMap存储
去重并保留迭代顺序,可为插入顺序或是访问顺序