Set
public interface Set<E>
extends Collection<E>
Set为不允许重复的集合。Set接口实现Collection接口。
HashSet
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, Serializable
HashSet继承AbstractSet<E>,无序不可重复集合。
TreeSet
public class TreeSet<E>
extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, Serializable
TreeSet继承AbstractSet<E>,有序,不可重复集合,按照字母顺序重新排序。
LinkedHashSet
public class LinkedHashSet<E>
extends HashSet<E>
implements Set<E>, Cloneable, Serializable
继承HashSet,有序,不可重复集合,按照插入顺序排序。
Set hs = new HashSet();
hs.add("Jim");
hs.add("HanMei");
hs.add("liLei");
hs.add("Jim");
System.out.println(" HashSet无序 不可重复 *******" + hs);
Iterator hsIterator = hs.iterator();
while (hsIterator.hasNext()) {
System.out.println("遍历HashSet : " + hsIterator.next());
}
Set ts = new TreeSet();
ts.add("efg");
ts.add("abc");
ts.add("hij");
ts.add("abc");
System.out.println(" TreeSet 有序 按照字母顺序排序 不可重复 ********" + ts);
Iterator tsIterator = ts.iterator();
while (tsIterator.hasNext()) {
System.out.println("遍历TreeSet : " + tsIterator.next());
}
HashSet lhs = new LinkedHashSet();
lhs.add("bcdea");
lhs.add("abcde");
lhs.add("cdeab");
lhs.add("abcde");
System.out.println(" LinkedHashSet 有序 按照插入顺序排序 不可重复 *********" + lhs);
Iterator lhsIterator = lhs.iterator();
while (lhsIterator.hasNext()) {
System.out.println("遍历lhsIterator : " + lhsIterator.next());
}
List
public interface List<E>
extends Collection<E>
有序集合(也称为序列)。该接口的用户可以精确控制每个元素在列表中的插入位置。用户可以通过整数索引(在列表中的位置)访问元素,并在列表中搜索元素。
ArrayList
public class ArrayList<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
列表接口的可变数组实现。实现所有可选的列表操作,并允许所有元素,包括null。除了实现List接口之外,该类还提供了一些方法来操作内部用于存储List的数组的大小。
有序,存储空间连续,可重复,根据下标获取元素,查询快,增删慢。
ArrayList新建对象方式:
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private transient Object[] elementData;
//定义制定大小集合
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
//空集合
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
}
//其他元素类型集合
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
ArrayList扩容方式:
private int size;
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
LinkedList
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, Serializable
数据结构为双向链表,增删快,只需要调整前后节点,查询慢,需要从头到尾遍历列表。有序、可为null。
双链表实现的列表和Deque接口。实现所有可选的列表操作,并允许所有元素(包括null)。
所有操作的执行都与双链表的预期一致。索引到列表中的操作将从头到尾遍历列表,以更接近指定索引的操作为准。
请注意,此实现不是同步的。如果多个线程并发地访问一个链表,并且其中至少有一个线程在结构上修改了链表,那么它必须在外部同步。(结构修改是指添加或删除一个或多个元素的任何操作;仅仅设置元素的值不是结构修改。这通常是通过对一些自然封装列表的对象进行同步来完成的。如果不存在这样的对象,则应该使用集合“包装”列表。synchronizedList方法。这最好在创建时完成,以防止对列表的意外非同步访问:
列表=集合。synchronizedList(new LinkedList(…));该类的迭代器和listIterator方法返回的迭代器是fail-fast:如果在创建迭代器之后,列表在结构上以任何方式被修改,除了通过迭代器自己的删除或添加方法,迭代器将抛出一个ConcurrentModificationException异常。因此,面对并发修改,迭代器会快速而干净地失败,而不是在将来某个不确定的时间冒险进行任意的、不确定的行为。
请注意,迭代器的快速失败行为不能得到保证,因为一般来说,在非同步并发修改的情况下不可能做出任何硬保证。失败快速迭代器以最大的努力抛出ConcurrentModificationException。因此,编写一个依赖于这个异常的正确性的程序是错误的:迭代器的快速失败行为应该只用于检测错误。
该类是Java集合框架的成员。
Vector
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
与ArrayList类似,只是方法增加synchronized关键字。同步,线程安全。
Vector类实现了一个可扩展的对象数组。像数组一样,它包含可以使用整数索引访问的组件。但是,在创建了向量之后,可以根据需要增加或减少向量的大小,以适应添加和删除项。
每个向量都试图通过保持容量和容量增量来优化存储管理。容量总是至少和矢量大小一样大;它通常比较大,因为当向向量中添加组件时,向量的存储以块的形式增加,块的大小等于capacityIncrement。应用程序可以在插入大量组件之前增加向量的容量;这减少了增量重新分配的数量。
这个类的迭代器和listIterator方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时候在结构上对向量进行了修改,除了通过迭代器自己的删除或添加方法,迭代器将抛出一个ConcurrentModificationException异常。因此,面对并发修改,迭代器会快速而干净地失败,而不是在将来某个不确定的时间冒险进行任意的、不确定的行为。元素方法返回的枚举不会很快失败。
请注意,迭代器的快速失败行为不能得到保证,因为一般来说,在非同步并发修改的情况下不可能做出任何硬保证。失败快速迭代器以最大的努力抛出ConcurrentModificationException。因此,编写一个依赖于这个异常的正确性的程序是错误的:迭代器的快速失败行为应该只用于检测错误。
在Java 2平台v1.2中,该类经过了改进以实现List接口,使其成为Java集合框架的成员。与新的集合实现不同,Vector是同步的。如果不需要线程安全的实现,建议使用ArrayList代替Vector。
代码示例:
List<String> al = new ArrayList<String>();
al.add("bcdea");
al.add("abcde");
al.add("cdeab");
al.add("abcde");
al.add(null);
al.add(null);
System.out.println("ArrayList 有序 可重复集合,按照插入顺序排除,允许null ********** " + al);
Iterator alIterator = al.iterator();
while (alIterator.hasNext()) {
System.out.println("遍历ArrayList : " + alIterator.next());
}
List<String> ll = new LinkedList<String>();
ll.add("eabcd");
ll.add("deabc");
ll.add("abcde");
ll.add("deabc");
ll.add(null);
System.out.println(" LinkedList 有序,可重复,按照插入顺序排序,允许为null********" + ll);
Iterator llIterator = ll.iterator();
while (llIterator.hasNext()) {
System.out.println("遍历LinkedList : " + llIterator.next());
}
List<String> vl = new Vector<String>();
vl.add("eabcd");
vl.add("deabc");
vl.add("abcde");
vl.add("deabc");
vl.add(null);
System.out.println(" Vector 有序,可重复,按照插入顺序排序,允许为null********" + ll);
Iterator vlIterator = vl.iterator();
while (vlIterator.hasNext()) {
System.out.println("遍历Vector : " + vlIterator.next());
}
Map
public interface Map<K,V>
将键映射到值的对象。映射不能包含重复的键;每个键最多只能映射到一个值。
HashMap
public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
基于哈希表的映射接口实现。这个实现提供了所有可选的映射操作,并允许空值和空键。(HashMap类大致相当于Hashtable,只是它是非同步的,并且允许为空。)这个类不保证映射的顺序;特别是,它不能保证顺序随时间保持不变。
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
static final int MAXIMUM_CAPACITY = 1 << 30;
static final float DEFAULT_LOAD_FACTOR = 0.75f;
static final Entry<?,?>[] EMPTY_TABLE = {};
transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;
transient int size;
final float loadFactor;
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
threshold = initialCapacity;
init();
}
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap() {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
}
public HashMap(Map<? extends K, ? extends V> m) {
this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
inflateTable(threshold);
putAllForCreate(m);
}
private void inflateTable(int toSize) {
// Find a power of 2 >= toSize
int capacity = roundUpToPowerOf2(toSize);
threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
table = new Entry[capacity];
initHashSeedAsNeeded(capacity);
}
private static int roundUpToPowerOf2(int number) {
// assert number >= 0 : "number must be non-negative";
return number >= MAXIMUM_CAPACITY
? MAXIMUM_CAPACITY
: (number > 1) ? Integer.highestOneBit((number - 1) << 1) : 1;
}
final boolean initHashSeedAsNeeded(int capacity) {
boolean currentAltHashing = hashSeed != 0;
boolean useAltHashing = sun.misc.VM.isBooted() &&
(capacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD);
boolean switching = currentAltHashing ^ useAltHashing;
if (switching) {
hashSeed = useAltHashing
? sun.misc.Hashing.randomHashSeed(this)
: 0;
}
return switching;
}
private void putAllForCreate(Map<? extends K, ? extends V> m) {
for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
putForCreate(e.getKey(), e.getValue());
}
private void putForCreate(K key, V value) {
int hash = null == key ? 0 : hash(key);
int i = indexFor(hash, table.length);
/**
* Look for preexisting entry for key. This will never happen for
* clone or deserialize. It will only happen for construction if the
* input Map is a sorted map whose ordering is inconsistent w/ equals.
*/
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k)))) {
e.value = value;
return;
}
}
createEntry(hash, key, value, i);
}
void createEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<>(hash, key, value, e);
size++;
}