//多参照:http://cmsblogs.com/?cat=5
List之subList细节
1、subList返回的只是原列表的一个视图,它所有的操作最终都会作用在原列表上
2、生成子列表后,不要试图去操作原列表,否则会造成子列表的不稳定而产生异常
3、利用subList清除原列表中其中一部分,原因是子列表的操作都会反映在原列表上
public class LList {
public static void main(String[] args) {
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
for(Integer i: list) System.out.print(i + " ");
System.out.println();
//point3: 利用subList清除原列表中的其中一部分,原因是子列表的操作都会反映在原列表上
list.subList(0, 1).clear();
for(Integer i: list) System.out.print(i + " ");
System.out.println();
//point1: subList返回的只是原列表的一个视图,它所有的操作最终都会作用在原列表上
List sublist = list.subList(0, list.size());
//point2: 生成子列表后,不要试图去操作原列表,否则会造成子列表的不稳定而产生异常
list.add(5);
for(Integer i: sublist) System.out.print(i + " ");
}
}
Arrays.asList细节
1、在使用asList时不要将基本数据类型当做参数(个人认为指定List的泛型类型就可以避免明白该注意点)
2、不要试图改变asList返回的列表,该list是一个长度不可变的列表,传入参数的数组有多长,其返回列表就多长
public class LList {
public static void main(String[] args) {
int[] is = {2, 4, 6, 8, 10};
List list1 = Arrays.asList(is);
//List list1 = Arrays.asList(is);
Integer[] its = {2, 4, 6, 8, 10};
List list2 = Arrays.asList(its);
//List list2 = Arrays.asList(its);
System.out.println(list1.size() + "\t" + list2.size());
list2.remove(1);
}
}
集合之初始容量细节(List为例)
JDK对List、Map的容量、加载因子的解释:
1、ArrayList实例都有一个容量
该容量是指用来存储列表元素的数组的大小,它总是至少等于列表的大小。随着向 ArrayList中不断添加元素,其容量也自动增长,并未指定增长策略的细节,因为这不只是添加元素会带来分摊固定时间开销那样简单
2、HashMap的实例有两个参数影响其性能:初始容量和加载因子
容量是哈希表中桶的数量,初始容量只是哈希表在创建时的容量。
加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。
当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。
其他:对于ArrayList和HashMap并不是线程安全的,故在使用的时候要注意该特点;
public class LList {
public static void main(String[] args) {
int count = 10000000;
//初始化的容量是10,(oldCapacity * 3)/2 + 1;扩容1.5倍
List list1 = new ArrayList();
List list2 = new ArrayList(count);
long begin1 = System.currentTimeMillis();
for (int i = 0; i < count; i++) list1.add(i);
long end1 = System.currentTimeMillis();
System.out.println("test 1 cost: " + (end1 - begin1));
for (int i = 0; i < count; i++) list2.add(i);
long end2 = System.currentTimeMillis();
System.out.println("test 2 cost: " + (end2 - end1));
//test 1 cost: 1413
//test 2 cost: 279
}
}
List细节(Vector, ArrayList, LinkedList)
+-----------------------------------------------------------------------------------------------------------------+
| Vector |
+-----------------------------------------------------------------------------------------------------------------+
| Vector() | 构造一个空向量,使其内部数据数组的大小为 10,其标准容量增 |
| | 量为零。 |
| Vector(Collection extends E> c) | 构造一个包含指定 collection 中的元素的向量,这些元素按其 |
| | collection 的迭代器返回元素的顺序排列。 |
| Vector(int initialCapacity) | 使用指定的初始容量和等于零的容量增量构造一个空向量。 |
| Vector(int initialCapacity, int capacityIncrement) | 使用指定的初始容量和容量增量构造一个空的向量。 |
+-----------------------------------------------------------------------------------------------------------------+
|线程安全: Vector是同步; |
|集合扩容:若capacityIncrement <= 0则扩大一倍,否则扩大至capacityIncrement。当然这个容量的最大范围为Integer.MAX_V |
| ALUE即,2^32 – 1,所以Vector并不是可以无限扩充的。 |
|底层实现:this.elementData = new Object[initialCapacity] |
+-----------------------------------------------------------------------------------------------------------------+
| ArrayList |
+-----------------------------------------------------------------------------------------------------------------+
| ArrayList() | 构造一个初始容量为 10 的空列表。 |
| ArrayList(Collection extends E> c) | 构造一个包含指定 collection的元素的列表,这些元素是按照该 |
| | collection 的迭代器返回它们的顺序排列的。 |
| ArrayList(int initialCapacity) | 构造一个具有指定初始容量的空列表。 |
+-----------------------------------------------------------------------------------------------------------------+
|线程安全:ArrayList是不同步; |
|集合扩容:重新计算容量,newCapcity = (oldCapacity * 3) / 2 + 1; |
|底层实现:this.elementData = new Object[initialCapacity] |
+-----------------------------------------------------------------------------------------------------------------+
| LinkedList |
+-----------------------------------------------------------------------------------------------------------------+
| LinkedList() | 构造一个空列表。 |
| LinkedList(Collection extends E> c) | 构造一个包含指定 collection 中的元素的列表,这些元素按其 |
| | collection 的迭代器返回的顺序排列。 |
+-----------------------------------------------------------------------------------------------------------------+
|线程安全:LinkedList是不同步; |
|集合扩容:增加新的节点 |
|底层实现:header.next = header.previous = header; |
+-----------------------------------------------------------------------------------------------------------------+
public class LList {
public static void main(String[] args) {
List vector = new Vector();
List arraylist = new ArrayList();
List linkedlist = new LinkedList();
int count = 100000;
long bt = System.currentTimeMillis();
add(vector, count);
long evt = System.currentTimeMillis();
System.out.println("vector add cost: " + (evt - bt));
add(arraylist, count);
long eat = System.currentTimeMillis();
System.out.println("arraylist add cost: " + (eat - evt));
add(linkedlist, count);
long elt = System.currentTimeMillis();
System.out.println("linkedlist add cost: " + (elt - eat));
System.out.println("=======================================");
read(vector);
long rvt = System.currentTimeMillis();
System.out.println("vector read cost: " + (rvt - elt));
read(arraylist);
long rat = System.currentTimeMillis();
System.out.println("arraylist read cost: " + (rat - rvt));
read(linkedlist);
long rlt = System.currentTimeMillis();
System.out.println("linkedlist read cost: " + (rlt - rat));
System.out.println("=======================================");
delete(vector, count);
long dvt = System.currentTimeMillis();
System.out.println("vector delete cost: " + (dvt - rlt));
delete(arraylist, count);
long dat = System.currentTimeMillis();
System.out.println("arraylist delete cost: " + (dat - dvt));
delete(linkedlist, count);
long dlt = System.currentTimeMillis();
System.out.println("linkedlist delete cost: " + (dlt - dat));
/*
* vector add cost: 9
* arraylist add cost: 6
* linkedlist add cost: 5
* =======================================
* vector read cost: 8
* arraylist read cost: 8
* linkedlist read cost: 9
* =======================================
* vector delete cost: 1061
* arraylist delete cost: 1063
* linkedlist delete cost: 5
*/
}
}
Map细节(HashMap、Hashtable、TreeMap)
/*
* +----E---> [C]LinkedHashMap
* |
* +---I---> [C]HashMap
* [I]Map ---+---I---> [C]TreeMap
* +---I---> [C]WeakHashMap
* +---I---> [C]Hashtable
*
* TreeMap -----> [I]NavigableMap --E--> SortedMap --E--> Map
* TreeMap --E--> [C]AbstractMap -----> Map
* TreeMap的key不能为null
*
* HashMap 和 Hashtable的异同点:
* 相同点:都实现了Map、Cloneable、Serializable接口;底层都是基于单链表实现
* 不同点: 1.HashMap线程非安全;Hashtable线程安全
* 2.HashMap的key, value都可以为null;Hashtable的key, value都不能为null
* 3.HashMap继承自AbstractMap;Hashtable继承自Dictionary
* TreeMap的内部结构是一棵红黑树(又叫排序数,是二叉树的一种),使用链式存储,可以指定比较器Comparator,
* key需实现Comparable接口。key不能为null。存结点性能稍差,因为需要调整树结构;取结点用的是链表遍历,但
* 是属于有序比较,性能中等。迭代遍历时用的树的中序遍历,是一个有序序列。适用于有排序需求的情况。
*/
public class LMap {
public static void main(String[] args) {
Map hashmap = new HashMap();
Map hashtable = new Hashtable();
Map treemap = new TreeMap();
int count = 100000;
System.out.println("hashmap put cost: " + put(hashmap, count));
System.out.println("hashtable put cost: " + put(hashtable, count));
System.out.println("treemap put cost: " + put(treemap, count));
System.out.println("============================================");
System.out.println("hashmap read cost: " + read(hashmap));
System.out.println("hashtable read cost: " + read(hashtable));
System.out.println("treemap read cost: " + read(treemap));
System.out.println("============================================");
System.out.println("hashmap delete cost: " + delete(hashmap, count));
System.out.println("hashtable delete cost: " + delete(hashtable, count));
System.out.println("treemap delete cost: " + delete(treemap, count));
//hashmap put cost: 56
//hashtable put cost: 44
//treemap put cost: 49
//hashmap read cost: 16
//hashtable read cost: 19
//treemap read cost: 23
//hashmap delete cost: 37
//hashtable delete cost: 22
//treemap delete cost: 39
}
}