博客出自:http://blog.csdn.net/liuxian13183,转载注明出处! All Rights Reserved !
ArrayList是一个动态数组,有下标
LinkedList是一个双向链表,一个指针指向下一个
相同点:都继承自Collections类,放动态数据。
不同点:
后者有指针,增加一个数据,只用断开一个连接,分别将新数据连上
删除一个数据,区别在于如果这个数据位于数组中间,后者只用查到该数据,断开一个连接,将两边的数据连上;
而前者需要将后面所有数据移位
修改,对于后者来说,就是删除+增加;而后者需要移位。
查找,前者通过下标查找方便,后者需要一个指针指向下一个指针来寻找数据,比较慢。
offer==add:添加一个值到尾部,offer是使用add方法实现的。
peek:获得第1个值。
pop:获得第1个值并删除。
poll:获得第1个值并删除,与pop不同的是如果第1个值为null,pop抛出NoSuchElementException,而poll仅返回null。
Vector使用数组实现,其实跟ArrayList一样,区别仅在于实现同步,即不同线程可以共用一个数据。但它不会对遍历如iterator加锁,仅set、get、remove等常用操作加锁,在这一点上HashTable同理。
HashMap底层使用数组+链表实现,同一个键可以放多个值,但取出的是最后一个,非同步,允许放空值空键
HashTable与HashMap一样,唯一不同就是,它是线程安全的,put、get等操作都加锁,且不允许空值空键。
查找都根据key的hash来定位数组的下标。
LinkedHashMap与LinkedArrayList原理相似,可以放空值空键,非同步;相比HashMap是个单向链表来讲,它是个双向链表,可以不像单向链表一样从头开始查找数据,是单向链表的升级;缺点:保留原值。
我们能否让HashMap同步?可以通过下面语句同步:
Map map=Collections.sychronizedMap(hashmap);
如果要完全的线程安全可以考虑CopyOnWriteArrayList和ConcurrentHashMap。它们使用volatile和synchronzied来保持同步。
Collections.unmodifiableList(list);
上面的方法可使当前list无法再添加对象,保持数据传递的安全性。
Android提供一个新的API:SpareArray,来替换ArrayList,特点不存空值,在跟下标有关的操作中,都会执行一遍回收操作,将空值移除提高查找和增加效率。Hash:指针对一段数据做的指纹(fingerprint)或者叫摘要(diget),用于快速查找。hash一般保证值不相等,防止暴力碰撞和篡改; 如果值相等,则需要继续当前算法,直到不等为止(再散列法),还有开放寻址法、再建公共溢出区法等等。常见的hash算法有Md5和Sha等。
比如HashMap,查找时不是比较key,而是比较key的hash值,则速度更快。
再比如ArrayMap,使用数组结构,存储hash数组和value数组。put时,根据key和key得到的hash,来设计value的存储位置index,然后把旧值返回,将新的value存入; get时,根据key和key得到的hash,计算出index,从value数组中取得目标value。
最简单的就是String对象里的hashCode算法:
public static int hashCode(char[] value) { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; }
TreeSet、TreeMap是自动排序的,TreeSet使用TreeMap来实现。
TreeSet:
public class TreeSet
extends AbstractSet implements NavigableSet , Cloneable, java.io.Serializable { /** * The backing map. */ private transient NavigableMap m; public boolean add(E e) { return m.put(e, PRESENT)==null; }
private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in any hidden stuff s.defaultReadObject(); // Read in Comparator @SuppressWarnings("unchecked") Comparator super E> c = (Comparator super E>) s.readObject(); // Create backing TreeMap TreeMap
tm = new TreeMap<>(c); m = tm; // Read in size int size = s.readInt(); tm.readTreeSet(size, s, PRESENT); } TreeMap: 通过Comparator接口实现升级排序
public V put(K key, V value) { TreeMapEntry
t = root; if (t == null) { // We could just call compare(key, key) for its side effect of checking the type and // nullness of the input key. However, several applications seem to have written comparators // that only expect to be called on elements that aren't equal to each other (after // making assumptions about the domain of the map). Clearly, such comparators are bogus // because get() would never work, but TreeSets are frequently used for sorting a set // of distinct elements. // // As a temporary work around, we perform the null & instanceof checks by hand so that // we can guarantee that elements are never compared against themselves. // // compare(key, key); // // **** THIS CHANGE WILL BE REVERTED IN A FUTURE ANDROID RELEASE **** if (comparator != null) { if (key == null) { comparator.compare(key, key); } } else { if (key == null) { throw new NullPointerException("key == null"); } else if (!(key instanceof Comparable)) { throw new ClassCastException( "Cannot cast" + key.getClass().getName() + " to Comparable."); } } root = new TreeMapEntry<>(key, value, null); size = 1; modCount++; return null; } int cmp; TreeMapEntry parent; // split comparator and comparable paths Comparator super K> cpr = comparator; if (cpr != null) { do { parent = t; cmp = cpr.compare(key, t.key); if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else return t.setValue(value); } while (t != null); } else { if (key == null) throw new NullPointerException(); @SuppressWarnings("unchecked") Comparable super K> k = (Comparable super K>) key; do { parent = t; cmp = k.compareTo(t.key); if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else return t.setValue(value); } while (t != null); } TreeMapEntry e = new TreeMapEntry<>(key, value, parent); if (cmp < 0) parent.left = e; else parent.right = e; fixAfterInsertion(e); size++; modCount++; return null; } 附Java层次关系图:
如图所示:图中,实线边框的是实现类,折线边框的是抽象类,而点线边框的是接口
有关集合类的排序和其他介绍请移步:
http://blog.csdn.net/liuxian13183/article/details/7557957
Java集合汇总:https://hacpai.com/article/1523869541981