




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、集合类说明及区别CollectionListLinkedListArrayListVectorStackSetMapHashtableHashMapWeakHashMapCollection接口Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。一些 Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。所有实现Collection接口的类都必须提供两
2、个标准的构造函数:无参数的构造函数用于创建一个空的Collection,有一个 Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection。如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:Iterator it = collection.iterator(); / 获得一个迭代子while(i
3、t.hasNext() Object obj = it.next(); / 得到下一个元素由Collection接口派生的两个接口是List和Set。List接口List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。和下面要提到的Set不同,List允许有相同的元素。除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个 ListIterator接口,和标准的Iterator接口相比,Lis
4、tIterator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历。实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。LinkedList类LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在 LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。注意LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建Li
5、st时构造一个同步的List:List list = Collections.synchronizedList(new LinkedList(.);ArrayList类ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入前可
6、以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。和LinkedList一样,ArrayList也是非同步的(unsynchronized)。Vector类Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和 ArrayList创建的Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了 Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出 ConcurrentModificationException
7、,因此必须捕获该异常。Stack 类Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。Set接口Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。很明显,Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。请注意:必须小心操作可变对象(
8、Mutable Object)。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。Map接口请注意,Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个 value。Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。Hashtable类Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value。添加数据使用p
9、ut(key, value),取出数据使用get(key),这两个基本操作的时间开销为常数。Hashtable通过initial capacity和load factor两个参数调整性能。通常缺省的load factor 0.75较好地实现了时间和空间的均衡。增大load factor可以节省空间但相应的查找时间将增大,这会影响像get和put这样的操作。使用Hashtable的简单示例如下,将1,2,3放到Hashtable中,他们的key分别是”one”,”two”,”three”:Hashtable numbers = new Hashtable();numbers.put(“one”,
10、 new Integer(1);numbers.put(“two”, new Integer(2);numbers.put(“three”, new Integer(3);要取出一个数,比如2,用相应的key:Integer n = (Integer)numbers.get(“two”);System.out.println(“two = ” + n);由于作为key的对象将通过计算其散列函数来确定与之对应的value的位置,因此任何作为key的对象都必须实现hashCode和equals方法。hashCode和equals方法继承自根类Object,如果你用自定义的类当作key的话,要相当小
11、心,按照散列函数的定义,如果两个对象相同,即obj1.equals(obj2)=true,则它们的hashCode必须相同,但如果两个对象不同,则它们的hashCode不一定不同,如果两个不同对象的hashCode相同,这种现象称为冲突,冲突会导致操作哈希表的时间开销增大,所以尽量定义好的hashCode()方法,能加快哈希表的操作。如果相同的对象有不同的hashCode,对哈希表的操作会出现意想不到的结果(期待的get方法返回null),要避免这种问题,只需要牢记一条:要同时复写equals方法和hashCode方法,而不要只写其中一个。Hashtable是同步的。HashMap类HashM
12、ap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null key。,但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开销和HashMap 的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load factor过低。WeakHashMap类WeakHashMap是一种改进的HashMap,它对key实行“弱引用”,如果一个key不再被外部所引用,那么该key可以被GC回收。总结如果涉及到堆栈,队列等操作,应该考虑用Lis
13、t,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。同步性Vector是同步的。这个类中的一些方法保证了Vector中的对象是线程安全的。而Arr
14、ayList则是异步的,因此ArrayList中的对象并不是线程安全的。因为同步的要求会影响执行的效率,所以如果你不需要线程安全的集合那么使用ArrayList是一个很好的选择,这样可以避免由于同步带来的不必要的性能开销。数据增长从内部实现机制来讲ArrayList和Vector都是使用数组(Array)来控制集合中的对象。当你向这两种类型中增加元素的时候,如果元素的数目超出了内部数组目前的长度它们都需要扩展内部数组的长度,Vector缺省情况下自动增长原来一倍的数组长度,ArrayList是原来的50%,所以最后你获得的这个集合所占的空间总是比你实际需要的要大。所以如果你要在集合中保存大量的
15、数据那么使用Vector有一些优势,因为你可以通过设置集合的初始化大小来避免不必要的资源开销。使用模式在ArrayList和Vector中,从一个指定的位置(通过索引)查找数据或是在集合的末尾增加、移除一个元素所花费的时间是一样的,这个时间我们用 O(1)表示。但是,如果在集合的其他位置增加或移除元素那么花费的时间会呈线形增长:O(n-i),其中n代表集合中元素的个数,i代表元素增加或移除元素的索引位置。为什么会这样呢?以为在进行上述操作的时候集合中第i和第i个元素之后的所有元素都要执行位移的操作。这一切意味着什么呢?这意味着,你只是查找特定位置的元素或只在集合的末端增加、移除元素,那么使用V
16、ector或ArrayList都可以。如果是其他操作,你最好选择其他的集合操作类。比如,LinkList集合类在增加或移除集合中任何位置的元素所花费的时间都是一样的?O(1),但它在索引一个元素的使用缺比较慢O(i),其中i是索引的位置.使用ArrayList也很容易,因为你可以简单的使用索引来代替创建iterator对象的操作。LinkList也会为每个插入的元素创建对象,所有你要明白它也会带来额外的开销。最后,在Practical Java一书中Peter Haggar建议使用一个简单的数组(Array)来代替Vector或ArrayList。尤其是对于执行效率要求高的程序更应如此。因为使
17、用数组 (Array)避免了同步、额外的方法调用和不必要的重新分配空间的操作。相互区别Vector和ArrayList1,vector是线程同步的,所以它也是线程安全的,而arraylist是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用arraylist效率比较高。2,如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度的50%.如过在集合中使用数据量比较大的数据,用vector有一定的优势。3,如果查找一个指定位置的数据,vector和arraylist使用的时间是相同的,都是0(1),这个时候使用
18、vector和arraylist都可以。而如果移动一个指定位置的数据花费的时间为0(n-i)n为总长度,这个时候就应该考虑到使用linklist,因为它移动一个指定位置的数据所花费的时间为0(1),而查询一个指定位置的数据时花费的时间为0(i)。ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动等内存操作,所以索引数据快插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数
19、据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快!arraylist和linkedlist1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数据,LinkedList的
20、速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。HashMap与TreeMap 1、HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。HashMap中元素的排列顺序是不固定的)。 2、 HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定
21、的)。集合框架”提供两种常规的Map实现:HashMap和TreeMap (TreeMap实现SortedMap接口)。 3、在Map 中插入、删除和定位元素,HashMap 是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明确定义了hashCode()和 equals()的实现。这个TreeMap没有调优选项,因为该树总处于平衡状态。 结过研究,在原作者的基础上我还发现了一点,二树map一样,但顺序不一样,导致hashCode()不一样。 同样做测试: 在hashMap中,同样的值的map,顺序不同,equals时,false;
22、 而在treeMap中,同样的值的map,顺序不同,equals时,true,说明,treeMap在equals()时是整理了顺序了的。hashtable与hashmap一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现 二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的 三.值:只有HashMap可以让你将空值作为一个表的条目的key或value 五个最常用的集合类之间的区别和联系 1ArrayList: 元素单个,效率高,多用于查询
23、160; 2Vector: 元素单个,线程安全,多用于查询 3LinkedList:元素单个,多用于插入和删除 4HashMap: 元素成对,元素可为空 5HashTable: 元素成对,线程安全,元素不可为空 ArrayList 底层是Object数组,所以ArrayList具有数组的查询速度快的优点以及增删速度慢的缺点。 而在LinkedList的底层是一种双向循环链表。在此链表上每一个数据节点都由三部分组成:前指针(指向前面的节点的位置),数据,后指针(指向后面的节点的位置)。最后一个节点的后指针指向第一个节点
24、的前指针,形成一个循环。 双向循环链表的查询效率低但是增删效率高。 ArrayList和LinkedList在用法上没有区别,但是在功能上还是有区别的。 LinkedList 经常用在增删操作较多而查询操作很少的情况下:队列和堆栈。 队列:先进先出的数据结构。 栈:后进先出的数据结构。 注意:使用栈的时候一定不能提供方法让不是最后一个元素的元素获得出栈的机会。 Vector (与ArrayList相似,区别是Vector是重量级的组件,使用使消耗的资源比较多。) 结论:在考虑并发的情况下用Vector(保证线程的安全)。 在不考虑并发的情况下用ArrayList(不能保证线程的安全)。Java
25、集合类详解集合中存放的是对象的引用,而非对象本身 ,出于表达上的便利,简称为"集合中的对象". Set(集):集合中的对象不按特定方式排列,并且没有重复对象,它的有些实现类能对集合中的对象按特定方式排列. set接口主要有两个实现类HashSet和TreeSet,HashSet类按照哈希算法来存取集合中的对象,存取速度比较快,HashSet类还有一个子类LinkedHashSet类,不仅实现了哈希算法,而且实现了链表数据结构,TreeSet类实现了SortedSet接口,具有排序功能. 那么,当一个新的对象加入到Set集合中,Set的add()方法是如何判断这个对象是否已经
26、存在于集合中的呢? boolean isExists=false; Iterator it=set.iterator(); while(it.hasNext() Object oldObject=it.next(); if(newObject.equals(oldObject) isExists=true; break; 可见,Set采用对象的equals()方法比较两个对象是否相等,而不是采用"="比较运算符,以下程序代码尽管两次调用了Set的add()方法, 实际上只加入了一个对象: Set set=new HashSet(); String s1=new String
27、("hello"); String s2=new String("hello"); set.add(s1); set.add(s2); 虽然变量s1和s2实际上引用的是两个内存地址不同的字符串对象,但是由于s2.equals(s1)的比较结果为true,因此Set认为他们是相等的对象,当第二次调用Set的add()方法时,add()方法不会把s2引用的字符串对象加入到集合中. HashSet类 按照哈希算法来存取集合中的对象,具有很好的存取性能,当HashSet向集合中加入一个对象时,会调用对象的hashCode()方法获得哈希码,然后根据这个哈希码进一
28、步计算出对象在集合中的存放位置. 在Object类中定义了hashCode()和equals()方法,Object类的euqals()方法按照内存地址比较对象是否相等,因此如果object1.equals(object2)为true,表明object1变量和object2变量十九上引用同一个对象.那么object1和object2的哈希码也应该相同.*如果用户定义的类覆盖了Object类的equals()方法,但是没有覆盖Object类的hashCode()方法,就会导致当object1.equals(object2)为true时,而object1和object2的哈希码不一定一样,这样使Ha
29、shSet无法正常工作. TreeSet类: 实现了SortedSet接口,能够对集合中的对象进行排序. 如: Set set=new TreeSet(); set.add(new Integer(7); set.add(new Integer(9); set.add(new Integer(8); Iterator it=set.iterator(); while(it.hasNext() System.out.println(it.next(); 输出结果为:6 7 8 当TreeSet向集合中加入一个对象时,会把它插入到有序的对象序列中,那么TreeSet是如何对对象进行排序的捏?Tre
30、eSet支持两种排序方式:自然排序和客户化排序,默认情况下是自然排序.在JDK中,有一部分类实现了Comparable接口,如Integer,Double和String等,Comparable接口有一个compareTo(Object o)方法,它返回整数类型,对于表达式pareTo(y),如果返回值为0,表示x和y相等,如果返回值大于0,表示x大于y,如果小于0,表示x<y. TreeSet调用对象的compareTo()方法比较集合中对象的大小,然后进行升序排序,这种方式称为自然排序. 客户化排序: java.util.Comparator接口用于指定具体的排序方式,它有个compa
31、re(Object obj1,Object obj2),用于比较两个对象的大小.当表达式compare(x,y)的值大于0,表示x大于y,小于0,表示x小于y,等于0,表示x等于y,如果想让TreeSet进按照Customer对象的name属性进行降序排列,可以先创建实现Comparator接口的类CustomerComparator,如: import java.util.*; public class CustomerComparator implements Comparator public int compare(Object o1,Object o2) Customer c1=(C
32、ustoemr)o1; Customer c2=(Customer)o2; if(c1.getName().compareTo(c2.getName()>0) return -1; if(c1.getName().compareTo(c2.getName()<0) return 1; return 0; 接下来在构造TreeSet的实例时,调用它的TreeSet(Comparator comparator)构造方法 Set set=new TreeSet(new CustomerComparator(); Customer c1=new Customer("TOM&quo
33、t;,15); Customer c2=new Customer("JACK",20); Customer c3=new Customer("MIKE",38); set.add(c1);set.add(c2);set.add(c3); Iterator it=set.iterator(); while(it.hasNext() Custoemr customer=(Customer)it.next(); System.out.println(customer.getName()+"" +customer.getAge() ; 当Tr
34、eeSet向集合中加入Customer对象时,会调用CustomerComparator类的compare()方法进行排序,以上Tree按照Custoemr对象的name属性进行降序排列,最后输出为: TOM 15 MIKE 38 JACK 16 List(列表):对象以线性方式存储,集合中的对象按索引位置排序,可以有重复对象,允许按照对象在集合中的索引位置检索对象. 实现类有LinkedList,ArrayList和Vector,LinkedList采用链表数据结构,而ArrayList代表大小可变的数组, Vector和 ArrayList比较相似,两者的区别在于Vecotr类的实现采用了
35、同步机制,而ArrayList没有使用同步机制/ List按索引排列: List list=new ArrayList(); list.add(new Integer(3); list.add(new Integer(4); list.add(new Integer(3); list.add(new Integer(2); List的get(int index)方法返回集合中由参数index指定的索引位置的对象,第一个加入到集合中的对象的索引位置为0, for( int i=0,i<list.size;i+) System.out.println(list.get(i); 输出结果为:3
36、 4 3 2. List只能对集合中的对象按索引位置排序,如果希望对List中的对象按其他特定方式排序,可以借助Comparator接口和Collections类. Collections类是Java集合API中的辅助类,它提供了操纵集合的各种静态方法,其中sort()方法用于对List中的对象进行排序: sort(List list):对List中的对象进行自然排序. sort(List list,Comparator comparator):对List中的对象进行客户化排序,comparator参数指定排序方式. 对以下List进行自然排序: List list=new ArrayList(); list.add(new Integer(3); list.add(new Integer(4); list.add(new Integer(3); list.add(new Integer(2); Collections.sort(list); for(int i=0;i<list.si
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 大学化学考试必考试题及答案解析
- 数字与图形搭配试题及答案2025
- 新能源汽车整车电气化设计试题及答案
- 建筑安全文化建设案例试题及答案
- 新疆哈密地区本年度(2025)小学一年级数学统编版专题练习(上学期)试卷及答案
- 教育教学反思与成果提升的途径试题及答案
- 家具行业的社会责任与品牌战略考题试题及答案
- 房屋制图标准试题及答案
- 家具市场中的流行趋势对产品设计的启示研究试题及答案
- 分析2025年创业扶持政策的评估标准试题及答案
- 《阅读文言文与鉴赏》-提高学生文言文阅读与鉴赏能力
- PDP性格测试表模板
- 医师执业变更注册申请审核表
- 2023建筑施工承插型套扣式钢管脚手架安全技术规程
- (完整版)各档口单品菜品毛利率核算表
- 信息隐藏技术全套教学课件
- 2023年云南省昆明市中考作文真题解析及欣赏:坚持的力量
- 2023年江苏泰州市第四人民医院招考聘用高层次人才11人模拟备考试卷(共1000题含答案解析)
- 工会换届选举请示样式
- 七年级音乐上册 《青少年管弦乐队指南》教学课件
- GB/T 22465-2008红花籽油
评论
0/150
提交评论