List、Set和Map
java 常用集合list与Set、Map区别及适用场景总结
Java中容器[Collection(List,Set,Queue),Map],迭代器(Iterator)和比较器(Comparator)及列表排序
-
List,Set都是继承自Collection接口,Map则不是
List特点:元素有放入顺序,元素可重复
Set特点:元素无放入顺序,元素不可重复,重复元素会覆盖掉 -
Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
-
ArrayList
动态数组
初始化若容量为0,默认建一个容量为10的数组
超过容量扩容1.5倍。oldCapacity+(oldCapacity>>1)
只序列化有元素的数据 -
Vector
线程安全的ArrayList
多数public方法都是sychronized
capacityIncrement 扩展因子,扩容 → 原+(扩展因子>0?扩展因子:原) -
LinkedList
双向链表
get(int index)看index离中间距离判断正序找还是倒序找。
- HashSet
不允许存储重复元素,无序
用hashMap实现,key是存放的数据,value统一是PRESENT
允许一个null的key
private static final Object PRESENT = new Object();
- TreeSet
自动排序
红黑树,不允许null
-
TreeMap
红黑树
适用于按自然顺序或自定义顺序遍历键(key)。 -
HashTable
线程安全的HashMap,用synchronize,性能低
key不允许为null,因为它对key直接hashcode(),为null会抛异常。
value也不允许为null
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {//value为null抛异常
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry<?,?> tab[] = table;
int hash = key.hashCode();//key为null抛异常
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Entry<K,V> entry = (Entry<K,V>)tab[index];
for(; entry != null ; entry = entry.next) {
if ((entry.hash == hash) && entry.key.equals(key)) {
V old = entry.value;
entry.value = value;
return old;
}
}
addEntry(hash, key, value, index);
return null;
}
-
HashMap
JDK1.7 HashMap
JDK1.8 对 HashMap 的优化 -
ConcurrentHashMap
JDK1.7 ConcurrentHashMap
JDK1.8 对ConcurrentHashMap的优化
作为hashmap的key的类必须重写hashcode方法,包装类都重写了hashcode方法?
- Arrays.asList()
- 该方法对于基本数据类型的数组支持并不好,当数组是基本数据类型时不建议使用
- 当使用asList()方法时,数组就和列表链接在一起了。当更新其中之一时,另一个将自动获得更新。因为asList获得的List实际引用的就是数组 注意:仅仅针对对象数组类型,基本数据类型数组不具备该特性。
- asList得到的数组是的没有add和remove方法的。因为asList返回的List是Arrays中的内部类,而该类并没有定义add和remove方法。
- 边遍历边删除的正确做法是用iterator的remove方法,而不是直接用list的remove方法