Java 集合框架
GarU25
8年前
<p>Java集合框架大致可以分为五个部分:List列表,Set集合、Map映射、迭代器、工具类</p> <p>List 接口通常表示一个列表(数组、队列、链表</p> <p>栈),其中的元素 <strong>可以重复</strong> 的是:ArrayList 和LinkedList,另外还有不常用的Vector。LinkedList实现来Queue接口,因此也可以作为队列使用。</p> <p>Set接口通常表示一个集合,其中的元素 <strong>不可以重复</strong> (通过hashcode和equals函数保证),常用的实现类有HashSet和TreeSet</p> <p>Map是一个 <strong>映射接口</strong> ,其中的每个元素都是一个 <strong>key-value键值对</strong> ,同样抽象类AbstractMap通过适配器模式实现了Map接口中的大部分函数,TreeMap</p> <p>HashMap、WeakHashMap等实现类都通过继承AbstractMap实现的,另外,不常用的HashTable直接实现了Map接口。</p> <p>Iterator是遍历集合的迭代器(不能遍历Map,只用来遍历Collection),Collection的实现类都实现了iterator()函数,它返回一个Iterator对象,用来遍历集合,ListIterator则专门用来遍历List。</p> <h2><strong>ArrayList</strong></h2> <p>ArrayList的内部实现是基于基础的对象数组的</p> <p>特点:</p> <ul> <li> <p>允许null元素</p> </li> <li> <p>顺序表</p> </li> <li> <p>线程不同步、查询速度快、增删</p> </li> <li> <p>大小可变满</p> </li> </ul> <h2><strong>LinkedList</strong></h2> <p>LinkedList: 内部采用链表来存储元素,支持快速插入/删除元素,但不支持高效地随机访问</p> <p>一般大家都知道ArrayList和LinkedList的大致区别:</p> <p>1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。</p> <p>2.对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。</p> <p>3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 <strong>ArrayList的内部实现是基于基础的对象数组的</strong> , LinkedList中的get方法是按照顺序从列表的一端开始检查,直到另外一端。对LinkedList而言,访问列表中的某个指定元素没有更快的方法了。 它们之间最主要的区别在于ArrayList是可改变大小的数组,而LinkedList是双向链接串列(doubly LinkedList) ,因为Array是基于索引(index)的数据结构,它使用索引在数组中搜索和读取数据是很快的。Array获取数据的时间复杂度是O(1),但是要删除数据却是开销很大的,因为这需要重排数组中的所有数据。</p> <pre> <code class="language-java">public class ArraylistandLinkedlist { public static final int N = 50000; public static List values; static { Integer vals[] = new Integer[N]; Random r = new Random(); for (int i = 0, currval = 0; i < N; i++) { vals[i] = new Integer(currval); currval += r.nextInt(100) + 1; } values = Arrays.asList(vals); } static long timeList(List lst) { long start = System.currentTimeMillis(); for (int i = 0; i < N; i++) { int index = Collections.binarySearch(lst, values.get(i)); if (index != i) System.out.println("***错误***"); } return System.currentTimeMillis() - start; } public static void main(String args[]) { System.out.println("ArrayList消耗时间:" + timeList(new ArrayList(values))); System.out.println("LinkedList消耗时间:" + timeList(new LinkedList(values))); } }</code></pre> <h2><strong>HashSet</strong></h2> <p>HashSet实现了Set接口,它 <strong>不允许</strong> 集合中有 <strong>重复的值</strong> ,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前, 要先确保对象 <strong>重写equals()和hashCode()方法</strong> ,这样才能比较对象的值是否相等,以确保set中没有储存相等的对象。如果我们没有重写这两个方法,将会使用这个方法的默认实现。</p> <p>特点</p> <ul> <li>线程同步</li> <li>不允许重复的值</li> </ul> <h2><strong>HashMap</strong></h2> <p>HashMap实现了Map接口,Map接口对键值对进行映射。 <strong>Map中不允许重复的键</strong> 。Map接口有两个基本的实现,HashMap和TreeMap。TreeMap保存了对象的排列次序,而HashMap则不能。 <strong>HashMap允许键和值为null。</strong> HashMap是非synchronized的,但collection框架提供方法能保证HashMap synchronized,这样多个线程同时访问HashMap时,能保证只有一个线程更改Map。</p> <p>HashMap是一种<key,value>的存储结构,能够快速将key的数据put方式存储起来,然后很快的通过get取出来”,“HashMap不是线程安全的, HashTable是线程安全的,通过synchronized实现的</p> <p>简单的说HashMap的存储结构是由 <strong>数组和链表</strong> 共同完成的</p> <p>HashMap是Y轴方向是数组,X轴方向就是链表的存储方式</p> <h2><strong>HashTable</strong></h2> <p>HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。主要的区别有:线程安全性,同步(synchronization),以及速度。</p> <p>HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value), 而Hashtable则不行)。 <strong>HashMap是非synchronized,而Hashtable是synchronized</strong> ,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。</p> <p>** 由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。HashMap不能保证随着时间的推移Map中的元素次序是不变的。</p> <pre> <code class="language-java">public class HashmapAndHashTable { public static void main(String... args) { HashMap<String, String> hashMap = new HashMap<String, String>(); hashMap.put("cn", "中国"); hashMap.put("us", "米国"); hashMap.put("en", "英国"); hashMap.put("",""); System.out.println(hashMap); System.out.println("cn" + hashMap.get("cn")); System.out.println(hashMap.containsKey("cn")); System.out.println(hashMap.keySet()); System.out.println(hashMap.isEmpty()); Hashtable table = new Hashtable(); table.put("key1", "value1");//键 和 值, table.put("key2", "value2"); table.put("key3", "value3");//相当于堆栈 后进先出 Enumeration e = table.keys();//创建枚举 while (e.hasMoreElements()) {//是否有元素 String key = (String) e.nextElement(); System.out.println(key + " : " + table.get(key)); } } }</code></pre> <p> </p> <p>来自:http://www.jianshu.com/p/32a1616fdf8c</p> <p> </p>