JAVA核心基础之集合总结

JAVA核心基础之集合

一.集合有两种基础接口:Collection,Map
二.Collection下又分为List ,Set,Queue
三.List中常见的实现类有以下四种

1.ArrayList(非线程安全的)

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
...
int newCapacity = oldCapacity + (oldCapacity >> 1);
...

ArrayList–基于数组实现,默认初始容量为10(可用构造方法指定初始容量),以后每次扩容其1.5倍,最大容容量为 Integer.MAX_VALUE - 8。

2.LinkedList(非线程安全的)

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

基于链表结构实现,因其结构的特殊性,只要内存足够,它的大小可以无限。但是在源码中LinkedList使用了
来记录其大小,也就是说LinkedList也有最大容量限制的,也就是Integer.MAX_VALUE。

3.Vector**(线程安全的)**

public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable

基于数组实现,默认初始容量为10(可通过构造方法指定),最大容量为Integer.MAX_VALUE - 8,其中特殊的是,它有一个包含两个参数的构造方法

public Vector(int initialCapacity, int capacityIncrement)

第一个参数为初始容量,第二个参数为容量增长长度,
增长策略为:

int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);

简单来说:如果给定的capacityIncrement > 0,那么就按给定的capacityIncrement来增长容量。
如果不指定,或者知道指定是 <= 0的数,则扩容长度为原来的2倍。
因为其所有public方法都加入了synchronized修饰,所以其线程安全。

4.Stack(线程安全的)

class Stack<E> extends Vector<E>

Stack 是 Vector 的子类,也就是说基于Vector实现,也是线程安全的,和Vector的增容策略是相同的


四.Set常见的实现类有以下三种:

1.HashSet

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable
..
private transient HashMap<E,Object> map;
...

基于HashMap(HashMap的子类)实现,默认初始容量为16,加载因子为0.75f,每次扩容为原来的两倍(HashMap的扩容策略)

public HashSet(int initialCapacity, float loadFactor)

可以指定初始容量和加载因子,最大容量为1 << 30,大约10亿,元素之间无序,存储也无序。

2.LinkedHashSet

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

HashSet的子类,元素之间有序,但是存储无序(在内存上不一定连续).

3.TreeSet

public class TreeSet<E> extends AbstractSet<E>
			    implements NavigableSet<E>, Cloneable, java.io.Serializable

线程不安全的,基于TreeMap实现,是一个有序的集合,TreeSet中将元素按照升序排列,元素自身要实现Comparable接口。


五.Queue常见的实现类有以下几种

1.ArrayBlockingQueue

NIO中的东西不在这讲

2.ArrayDeque(非线程安全)

只提供了一个构造方法,初始容量必须由构造方法指定

3.LinkedBlockingDeque

NIO中的东西不在这讲

4.LinkedList

上面写过了,就不重复了


六.Map

实现Map的数据结构主要由键值对组成,以下主要介绍比较常用的类:

1.HashMap(线程不安全)

			static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;

默认初始容量16

			static final int MAXIMUM_CAPACITY = 1 << 30;

最大容量2^30

			static final float DEFAULT_LOAD_FACTOR = 0.75f;

默认装填因子:0.75f

			 	void addEntry(int hash, K key, V value, int bucketIndex) {
			      ...
			            resize(2 * table.length);
			      ...
			  	}

当每次达到 table.length * 0.75f 时进行扩容,每次扩容为原来的二倍 。

2.Hashtable(线程安全的)

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

初始容量为11
线程安全是因为其在所有 public 方法上加了synchronized修饰,锁住了当前对象的调用。
扩容策略:每次扩容 1 倍 + 1

			int newCapacity = (oldCapacity << 1) + 1;

3.LinkedHashMap(非线程安全)

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

初始容量为16,加载因子:0.75f

public LinkedHashMap() {
       super();
       accessOrder = false;
}

4.ConcurrentHashMap(线程安全的)

本章介绍的是jdk1.7的分段锁的实现,jdk1.8采用了CAS的算法来实现ConCurrentHashMap的线程安全机制,
具体请参考:https://www.jianshu.com/p/21be831e851e

			public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V>, Serializable
			 static final float DEFAULT_LOAD_FACTOR = 0.75f;

默认加载因子为0.75f

			static final int DEFAULT_INITIAL_CAPACITY = 16;

默认容量16,不可变

			static final int DEFAULT_CONCURRENCY_LEVEL = 16;

并发等级 16(在一个瞬间最多允许16个线程同时操作),不可变

			static final int MAXIMUM_CAPACITY = 1 << 30;

最大容量 2^30

			static final int MIN_SEGMENT_TABLE_CAPACITY = 2;

最小分区表容量

			static final int MAX_SEGMENTS = 1 << 16

最大分区个数

每段用一个HashMap来实现存储,这个类比较特殊,在JDK1.6/1.7/1.8中实现各不相同,ConcurrentHashMap采用了分段锁的思想,只有在每个分段内,才存在竞争,而在不同的分段,程序是可以并发执行的,默认分区数量为16.

	*  Like {@link Hashtable} but unlike {@link HashMap}, this class
	*  does **not** allow null to be used as a key or value.

和Hashtable有点像,但是和HashMap不同,这个类的键和值都不允许为null。

ConcurrentHashMap对外采用的是异步,但是在内部对每个分区采用的是同步的形式,与HashTable相比提高了其并发操作的能力。

HashMap和HashTable的区别

HashMap是非线程安全的,HashTable是线程安全的,因为HashTable使用了同步代码,所以就效率来说HashTable 小于 HashMap.

HashMap key 和value都允许存null,但是HashTable 不允许null值的存在。

ArrayList 和 LinkedList 区别

ArrayList基于数组实现,元素之间是有序的,在空间上是连续的

LinkedList基于链表实现,元素之间是有序的,在空间上不连续

List 和 set 的区别

List元素之间是有序的,存储也是有序的。

Set元素之间不一定有序的(LinkedHashSet元素之间有序),存储上无序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值