读书人

集合类:Collection-List, Set, Map

发布时间: 2013-03-06 16:20:31 作者: rapoo

集合类:Collection--List, Set, Map
1.JAVA集合类集合类:Collection-List, Set, Map

最常用的集合有List, Set 和 MapList ------------LinkedList ------------ArrayList ------------Vector |-------Stack
Set------------HashSet |-------LinkedHashSet -------------SortedSet |------TreeSet
对于它们的数据是否可以重复出现,是否有序,有如下特点:集合类:Collection-List, Set, Map

2.List2.1 ArrayListList的本质是array。 它在插入操作时会自动增加其大小,如下图的JDK 1. 6提供的源码:

package set;import java.util.*;public class TestTreeSet {/** * 使用TreeSet改写上一个程序,按照字母顺序显示字符串 * @author Sun1956 */public static void main(String[] args) {//created a hash setSet<String> set = new HashSet<String>();//Addset.add("London");set.add("Paris");set.add("San Francisco");set.add("Beijing");set.add("New York");//create a tree setTreeSet<String> treeSet = new TreeSet<String>(set);//按字母顺序排序System.out.println("Sorted tree set: " + treeSet);System.out.println("first() : " + treeSet.first());  //返回第一个元素System.out.println("last() : " + treeSet.last());    //返回最后一个System.out.println("headSet() : " + treeSet.headSet("New York"));    //返回小于New York的所有元素System.out.println("tailSet() : " + treeSet.tailSet("New York"));    //返回大于等于New York的所有元素System.out.println("lower(\"P\"): " + treeSet.lower("P"));   //返回小于P的一个元素System.out.println("higher(\"P\"): " + treeSet.higher("P"));  //大于PSystem.out.println("floor(\"P\"): " + treeSet.floor("P"));    //小于等于PSystem.out.println("ceiling(\"P\"): " + treeSet.ceiling("P"));  //大于等于System.out.println("pollFirst(): " + treeSet.pollFirst());    //删除treeSet中第一个System.out.println("pollLast(): " + treeSet.pollLast());     //删除treeSet中最后一个System.out.println("New tree set: " + treeSet);  //输出删除后的treeSetSystem.out.println();}}

Result:Sorted tree set: [Beijing, London, New York, Paris, San Francisco]
first() : Beijing
last() : San Francisco
headSet() : [Beijing, London]
tailSet() : [New York, Paris, San Francisco]
lower("P"): New York
higher("P"): Paris
floor("P"): New York
ceiling("P"): Paris
pollFirst(): Beijing
pollLast(): San Francisco
New tree set: [London, New York, Paris]


4. Map4.1 HashTableHashTable 是线程安全的Map,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value。添加数据使用put(key, value),取出数据使用get(key),这两个基本操作的时间开销为常数。
由于作为key的对象将通过计算其散列函数来确定与之对应的value的位置,因此任何作为key的对象都必须实现hashCode和equals方法。hashCode和equals方法继承自根类Object,如果你用自定义的类当作key的话,要相当小心,按照散列函数的定义,如果两个对象相同,即obj1.equals(obj2)=true,则它们的hashCode必须相同,但如果两个对象不同,则它们的hashCode不一定不同,如果两个不同对象的hashCode相同,这种现象称为冲突,冲突会导致操作哈希表的时间开销增大,所以尽量定义好的hashCode()方法,能加快哈希表的操作。
如果相同的对象有不同的hashCode,对哈希表的操作会出现意想不到的结果(期待的get方法返回null),要避免这种问题,只需要牢记一条:要同时复写equals方法和hashCode方法,而不要只写其中一个。
4.2 HashMapHashMap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null key。,但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开销和HashMap的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load factor过低。

5. 总结如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。同步性
Vector是同步的。这个类中的一些方法保证了Vector中的对象是线程安全的。而ArrayList则是异步的,因此ArrayList中的对象并不是线程安全的。因为同步的要求会影响执行的效率,所以如果你不需要线程安全的集合那么使用ArrayList是一个很好的选择,这样可以避免由于同步带来的不必要的性能开销。
数据增长
从内部实现机制来讲ArrayList和Vector都是使用数组(Array)来控制集合中的对象。当你向这两种类型中增加元素的时候,如果元素的数目超出了内部数组目前的长度它们都需要扩展内部数组的长度,Vector缺省情况下自动增长原来一倍的数组长度,ArrayList是原来的50%,所以最后你获得的这个集合所占的空间总是比你实际需要的要大。所以如果你要在集合中保存大量的数据那么使用Vector有一些优势,因为你可以通过设置集合的初始化大小来避免不必要的资源开销。
使用模式
在ArrayList和Vector中,从一个指定的位置(通过索引)查找数据或是在集合的末尾增加、移除一个元素所花费的时间是一样的,这个时间我们用O(1)表示。但是,如果在集合的其他位置增加或移除元素那么花费的时间会呈线形增长:O(n-i),其中n代表集合中元素的个数,i代表元素增加或移除元素的索引位置。为什么会这样呢?以为在进行上述操作的时候集合中第i和第i个元素之后的所有元素都要执行位移的操作。这一切意味着什么呢?
这意味着,你只是查找特定位置的元素或只在集合的末端增加、移除元素,那么使用Vector或ArrayList都可以。如果是其他操作,你最好选择其他的集合操作类。比如,LinkList集合类在增加或移除集合中任何位置的元素所花费的时间都是一样的?O(1),但它在索引一个元素的使用缺比较慢-O(i),其中i是索引的位置.使用ArrayList也很容易,因为你可以简单的使用索引来代替创建iterator对象的操作。LinkList也会为每个插入的元素创建对象,所有你要明白它也会带来额外的开销。
最后,在《Practical Java》一书中Peter Haggar建议使用一个简单的数组(Array)来代替Vector或ArrayList。尤其是对于执行效率要求高的程序更应如此。因为使用数组(Array)避免了同步、额外的方法调用和不必要的重新分配空间的操作。
6.参考博文Java集合框架系列教程四:Set接口
Set接口类:HashSet、LinkedHashSet、TreeSet
Java集合框架面试问题集锦
Java学习笔记-LinkedHashSet
Java_常瑞鹏 java_List和Set集合
ARRAYLIST VECTOR LINKEDLIST区别(推荐)


读书人网 >编程

热点推荐