大公司Java集合类Java面试问题题你知道多少

Java集合面试题:[1]集合面试题、Java集合_百度经验
&&&&&&&&&求职技巧Java集合面试题:[1]集合面试题、Java集合听语音1234
百度经验:jingyan.baidu.comjava.util包中就包含了一系列重要的集合类,而对于集合类,主要需要掌握的就是它的内部结构,以及遍历集合的迭代模式。Java2的集合框架,抽其核心,主要有三种:List、Set和Map。如下图所示:百度经验:jingyan.baidu.com1集合类特性(几个常用类的区别)ArrayList:&元素单个,效率高,多用于查询& Vector:&元素单个,线程安全,多用于查询& LinkedList:&元素单个,多用于插入和删除& HashMap:&元素成对,元素可为空& HashTable:&元素成对,线程安全,元素不可为空WeakHashMap:&是一种改进的HashMap,它对key实行“弱引用”,如果一个key不再被外部所引用,那么该key可以被GC回收2Iterator&是什么一些集合类提供了内容遍历的功能,通过java.util.Iterator接口。这些接口允许遍历对象的集合。依次操作每个元素对象。当使用Iterators时,在获得Iterator的时候包含一个集合快照。通常在遍历一个Iterator的时候不建议修改集合本省。&Iterator与ListIterator有什么区别1. Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。&?&2. Iterator只能正向遍历集合,适用于获取移除元素。ListIerator继承Iterator,可以双向列表的遍历,同样支持元素的修改。比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。3Collection&和&Collections的区别Collection是集合类的上级接口,继承与他的接口主要有Set&和List.Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作List、Map、Set三个接口,存取元素时,各有什么特点List &以特定次序来持有元素,可有重复元素;Set &无法拥有重复元素,内部排序(无序);Map&保存key-value值,value可多值。&4HashMap和Hashtable的区别都属于Map接口的类,实现了将惟一键映射到特定的值上。&&&一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java&1.2引进的Map接口的一个实现&&二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的&&三.值:&HashMap&类没有分类或者排序。它允许一个&null&键和多个&null&值。&&Hashtable&类似于&HashMap,但是不允许&null&键和&null&值。四.效率:Hashtable&比&HashMap&慢,因为它是同步的。怎样使HashMap同步HashMap可以通过Map m = Collections.synchronizedMap(hashMap)来达到同步的效果。5ArrayList和Vector的区别ArrayList与Vector主要从二方面来说.&&一.同步性:&& Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的。二.操作:&& &由于Vector支持多线程操作,所以在性能上就比不上ArrayList了。三.数据增长:&&&&&& ArrayList和Vector都有一个初始的容量大小,当存储进去它们里面的元素个数超出容量的时候,就需要增加ArrayList和Vector的存储空间,每次增加存储空间的时候不是只增加一个存储单元,是增加多个存储单元。&&&&&& Vector默认增加原来的一倍,ArrayList默认增加原来的0.5倍。&&&&&& Vector可以由我们自己来设置增长的大小,ArrayList没有提供相关的方法。LinkedList与ArrayList有什么区别两者都实现的是List接口,不同之处在于:(1)、ArrayList是基于动态数组实现的,LinkedList是基于链表的数据结构。(2)、get访问List内部任意元素时,ArrayList的性能要比LinkedList性能好。LinkedList中的get方法是要按照顺序从列表的一端开始检查,直到另一端(3)、对于新增和删除操作LinkedList要强于ArrayList,因为ArrayList要移动数据附加:& & &&&LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。& & &&&注意LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:List list = Collections.synchronizedList(new LinkedList(…));6数组(Array)和列表集合(ArrayList)有什么区别下面列出了Array和ArrayList的不同点:&&& & & &Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。&& & & &Array大小是固定的,ArrayList的大小是动态变化的。&& & & &&ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator() &等等。& & & &对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。Enumeration接口和Iterator接口的区别有哪些& & & &Enumeration速度是Iterator的2倍,同时占用更少的内存。但是,Iterator远远比Enumeration安全,因为其他线程不能够修改正在被iterator遍历的集合里面的对象。同时,Iterator允许调用者删除底层集合里面的元素,这对Enumeration来说是不可能的。7HashSet和TreeSet有什么区别&&HashSet有以下特点:A. 无序(不能保证元素的排列顺序,顺序有可能发生变化)B. 不同步C. 允许空值(集合元素可以是null,可以放入多个null,但会自动覆盖)当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相 等注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对象通过equals方法比较返回true时,其hashCode也应该相同。另外,对象中用作equals比较标准的属性,都应该用来计算 hashCode的值。&TreeSet有以下特点:A. 有序&&&&& 1. TreeSet是由一个树形的结构来实现的(数据结构是二叉树),它里面元& & &&& & &&素是有序的&&&&& 2.TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于& & &&& & &排序状 态,支持两种排序方式,自然排序和定制排序。其中自然排序为& & &&& & & &默认的排序方式;定制排序,TreeSet中的对象元素需要实Comparable& & &&& & & &接口&&& TreeSet类中跟HashSet类一样也没有get()方法来获取列表中的元素,所以& &&&&也只能通过迭代器方法来获取& & 二叉树:&&&&&&&&&&B. 不允许空值&& & &&1. HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的,只不过& & &&& & &&Set用的只是Map的key& & &&2. Map的key和Set都有一个共同的特性就是集合的唯一性.TreeMap更是& & &&& & & &&多&了一个有序性.& & &&3. TreeSet类中跟HashSet类一样也没有get()方法来获取列表中的元素,所& & &&& & &&以也只能通过迭代器方法来获取& & &&4. HashSet是基于hash算法实现的,性能优于TreeSet,通常使用& & &&& & &&& & &&& & & HashSet。在我们需要对其中元素排序的时候才使用TreeSet。8HashMap,LinkedMap,TreeMap的区别HashMap,LinkedHashMap,TreeMap都属于Map。LinkedHashMap是HashMap的子类。Map 主要用于存储键(key)值(value)对,根据键得到值,因此键不允许键重复,但允许值重复&1.HashMap的内部结构是一个数组,线性顺序存储,二次结构使用线性的单链表。使用key的hashCode做二次hash之后,再截取小于数组长度的值为索引值。key可以为null,存在索引为0的位置上。由于使用了数组,所以有一个负载因子loadFactor的概念(临界阈值threshold)和resize。resize比较耗时,冲突时链式遍历查找也比较耗时,所以选定一个合适的初始容易比较重要。存取性能都较高。迭代遍历时一维使用数组,二维使用链表。 & &&& & &&HashMap& & &&& & &&是一个最常用的Map,它根据键的HashCode 值存储数据,根据键可以直& & & & & & &&接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的& & & & & &&键为N允许多条记录的值为 NHashMap不支持线程的同步,即任 & & & & & & 一&时刻可以有多个线程同时写HashM可能会导致数据的不一致。如 & & & & & & 果需要同步,可以用 Collections的synchronizedMap方法使HashMap & & & & & 具有同步的能力。 2.LinkedHashMap是HashMap的子类。内部结构是一个数组,线性顺序存储,二次结构使用线性的单链表,但同时内部维护了一个双向循环链表,可以保持顺序。access-order=false默认为使用新增存储顺序,access-order=true则指定使用读取和访问顺序。removeEldestEntry=false(当指定为true时,就是实现LRU算法的缓存容器,当然要指定淘汰时的使用频率和容量上限,其实是一个最近最少使用--&最近使用access-order=true/最新存储access-order=false)。存取性能较HashMap差-些,但相差不大。header.after为尾方向,header.before为首方向。迭代遍历时entrySet().iterator()跟HashMap一样(有点困惑,为什么不按线性顺序进行迭代,只能重写entrySet(),keySet()和values()方法)。适用于有缓存设计需求的情况(需继承)。
3.TreeMap的内部结构是一棵红黑树(又叫排序数,是二叉树的一种),使用链式存储,可以指定比较器Comparator,key需实现Comparable接口。key不能为null。存结点性能稍差,因为需要调整树结构;取结点用的是链表遍历,但是属于有序比较,性能中等。迭代遍历时用的树的中序遍历,是一个有序序列。适用于有排序需求的情况。&&END经验内容仅供参考,如果您需解决具体问题(尤其法律、医学等领域),建议您详细咨询相关领域专业人士。作者声明:本篇经验系本人依照真实经历原创,未经许可,谢绝转载。投票(12)已投票(12)有得(0)我有疑问(0)◆◆说说为什么给这篇经验投票吧!我为什么投票...你还可以输入500字◆◆只有签约作者及以上等级才可发有得&你还可以输入1000字◆◆如对这篇经验有疑问,可反馈给作者,经验作者会尽力为您解决!你还可以输入500字相关经验00100热门杂志第3期人生知识达人职场秘诀1041次分享第1期实现创业梦想1512次分享第1期轻松理财手册693次分享第2期晋升攻坚战454次分享第1期如何用互联网理财530次分享◆请扫描分享到朋友圈JAVA集合类(大公司面试喜欢问的) - 简书
JAVA集合类(大公司面试喜欢问的)
看了一些所谓大公司的JAVA面试问题,发现对于JAVA集合类的使用都比较看重似的,而自己在这方面还真的是所真甚少,抽空也学习学习吧。java.util包中包含了一系列重要的集合类,而对于集合类,主要需要掌握的就是它的内部结构,以及遍历集合的迭代模式。接口:CollectionCollection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建一个空的Collection,有一个Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection。主要的一个接口方法:boolean add(Ojbect c)虽然返回的是boolean,但不是表示添加成功与否,这个返回值表示的意义是add()执行后,集合的内容是否改变了(就是元素的数量、位置等有无变化)。类似的addAll,remove,removeAll,remainAll也是一样的。用Iterator模式实现遍历集合Collection有一个重要的方法:iterator(),返回一个Iterator(迭代器),用于遍历集合的所有元素。Iterator模式可以把访问逻辑从不同的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。典型的用法如下:Iterator it = collection.iterator();// 获得一个迭代器while(it.hasNext()) {Objectobj = it.next();// 得到下一个元素}不需要维护遍历集合的“指针”,所有的内部状态都由Iterator来维护,而这个Iterator由集合类通过工厂方法生成。每一种集合类返回的Iterator具体类型可能不同,但它们都实现了Iterator接口,因此,我们不需要关心到底是哪种Iterator,它只需要获得这个Iterator接口即可,这就是接口的好处,面向对象的威力。要确保遍历过程顺利完成,必须保证遍历过程中不更改集合的内容(Iterator的remove()方法除外),所以,确保遍历可靠的原则是:只在一个线程中使用这个集合,或者在多线程中对遍历代码进行同步。由Collection接口派生的两个接口是List和Set。List接口List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。和下面要提到的Set不同,List允许有相同的元素。除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历。实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。LinkedList类LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。注意LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:List list = Collections.synchronizedList(new LinkedList(...));ArrayList类ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。和LinkedList一样,ArrayList也是非同步的(unsynchronized)。Vector类Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和ArrayList创建的Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。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参数不能包含重复的元素。请注意:必须小心操作可变对象(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。添加数据使用put(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”, 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的话,要相当小心,按照散列函数的定义,如果两个对象相同,即obj1.equals(obj2)=true,则它们的hashCode必须相同,但如果两个对象不同,则它们的hashCode不一定不同,如果两个不同对象的hashCode相同,这种现象称为冲突,冲突会导致操作哈希表的时间开销增大,所以尽量定义好的hashCode()方法,能加快哈希表的操作。如果相同的对象有不同的hashCode,对哈希表的操作会出现意想不到的结果(期待的get方法返回null),要避免这种问题,只需要牢记一条:要同时复写equals方法和hashCode方法,而不要只写其中一个。Hashtable是同步的。HashMap类HashMap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null key。,但是将HashMap视为Collection时(values()方法可返回Collection),其迭代器操作时间开销和HashMap的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load factor过低。WeakHashMap类WeakHashMap是一种改进的HashMap,它对key实行“弱引用”,如果一个key不再被外部所引用,那么该key可以被GC回收。总结如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。
在线编程学习平台:http://t.cn/RgljBrf,程序员的梦工厂
微信公众号:慕课网(imooc-com)
标签(空格分隔): Java集合框架 面试题汇总 1. 什么是Java集合框架?请列举出集合(Collections framework)框架的一些好处? 通过使用集合框架的核心类可以减少开发成本,从而避免实现自己的集合类。 使用经过良好测试的集合类可以提高代码的质量。 使...
1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io的语法,虚拟机方面的语法。 1、一个&.java&源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个publ...
1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector、Stack、HashTable和Array。随着集合的广泛使用,Java1.2提出了囊括所有集合接口、实现和算法的集合框架。在保证线程安全的情况下使...
1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector、Stack、HashTable和Array。随着集合的广泛使用,Java1.2提出了囊括所有集合接口、实现和算法的集合框架。在保证线程安全的情况下使...
跟传统理财相比,网络理财有什么吸引人的东西呢?优势在哪里呢? 现在的年轻人习惯就是,能在家做的事情,从不出门解决,能在网上买得到的东西,也不会去实体店逛逛。也因为大部分的“宅”,衍生了很多只要动动手指就可以解决的事情,购物、外卖、订票、理财……。互联网的发展,必然会产生互联...
1 没有谁的路是一帆风顺的,没有谁的人生是不受挫折的,没有谁的生活是一成不变的。宇宙中的一切无时不在变化,月有阴晴圆缺,花有花开花落。生活亦如此,有好有坏,有难过去的坎也有平坦的大道。 以前总是很叼的说:假如生活欺骗了你,你也要欺骗回生活。其实,真正的生活中,如果一再和生活...
2017年全国联考公务员申论课程(直接点击购买) 2017年版联考讲义+历年参考答案单行本 免费下载
今天回家了,因为明天要教师资格证面试!做最早的一班车回来,六点半就到车站了,在依依不舍的跟老公道别后,一模包,却怎么也找不着手机了,突然想起手机放在书桌上充电的事实。我赶忙叫住已经远去的老公,告诉他我手机忘记他了,他无可奈何的看了我一眼,便转身跑了!他七点的班车,上班也是赶...
我给自己写下不嗔不恨,我以为心态改变就能有坦然、简单、清新的生活。然而,痛苦,媾和,麻烦是那么容易侵袭到我身上。是我做的失败,是我内心的劣等,还是这种环境下注定的悲哀? 突然发现,当自己考量还能坚持多久的时候,已经失去了坚持的勇气和信心。至少,我觉得没什么值得我去坚持得了,...看了一些所谓大公司的JAVA面试问题,发现对于JAVA集合类的使用都比较看重似的,而自己在这方面还真的是所真甚少,抽空也学习学习吧。
java.util包中包含了一系列重要的集合类,而对于集合类,主要需要掌握的就是它的内部结构,以及遍历集合的迭代模式。
接口:Collection
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。一 些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的&子接口&如List和Set。
所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建一个空的Collection,有一个 Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。后 一个构造函数允许用户复制一个Collection。
主要的一个接口方法:boolean add(Ojbect c)
虽然返回的是boolean,但不是表示添加成功与否,这个返回值表示的意义是add()执行后,集合的内容是否改变了(就是元素的数量、位置等有无变化)。类似的addAll,remove,removeAll,remainAll也是一样的。
用Iterator模式实现遍历集合
Collection有一个重要的方法:iterator(),返回一个Iterator(迭代器),用于遍历集合的所有元素。Iterator模式可以把访问逻辑从不同的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。典型的用法如下:
Iterator it = collection.iterator(); // 获得一个迭代器
while(it.hasNext()) {
Object obj = it.next(); // 得到下一个元素
不需要维护遍历集合的&指针&,所有的内部状态都由Iterator来维护,而这个Iterator由集合类通过工厂方法生成。
每一种集合类返回的Iterator具体类型可能不同,但它们都实现了Iterator接口,因此,我们不需要关心到底是哪种Iterator,它只需要获得这个Iterator接口即可,这就是接口的好处,面向对象的威力。
要确保遍历过程顺利完成,必须保证遍历过程中不更改集合的内容(Iterator的remove()方法除外),所以,确保遍历可靠的原则是:只在一个线程中使用这个集合,或者在多线程中对遍历代码进行同步。
由Collection接口派生的两个接口是List和Set。
List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。和下面要提到的Set不同,List允许有相同的元素。
除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个 ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素, 还能向前或向后遍历。
实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。
LinkedList类
LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在 LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
注意LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:
List list = Collections.synchronizedList(new LinkedList(&));
ArrayList类
ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。
size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。
每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。
和LinkedList一样,ArrayList也是非同步的(unsynchronized)。
Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和
ArrayList创建的Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了
Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出
ConcurrentModificationException,因此必须捕获该异常。
Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和
pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空
Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。
很明显,Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。
请注意:必须小心操作可变对象(Mutable Object)。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。
请注意,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。
添加数据使用put(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&, 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的话,要相当小心,按照
散列函数的定义,如果两个对象相同,即obj1.equals(obj2)=true,则它们的hashCode必须相同,但如果两个对象不同,则它们的
hashCode不一定不同,如果两个不同对象的hashCode相同,这种现象称为冲突,冲突会导致操作哈希表的时间开销增大,所以尽量定义好的
hashCode()方法,能加快哈希表的操作。
如果相同的对象有不同的hashCode,对哈希表的操作会出现意想不到的结果(期待的get方法返回null),要避免这种问题,只需要牢记一条:要同时复写equals方法和hashCode方法,而不要只写其中一个。
Hashtable是同步的。
HashMap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null
key。,但是将HashMap视为Collection时(values()方法可返回Collection),其迭代器操作时间开销和HashMap
的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load factor过低。
WeakHashMap类
WeakHashMap是一种改进的HashMap,它对key实行&弱引用&,如果一个key不再被外部所引用,那么该key可以被GC回收。
如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。
尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。
阅读(...) 评论()}

我要回帖

更多关于 Java面试问题 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信