java集合类框架的基本接口有哪些?
Collection:代表一组对象,每个对象都是他的子元素。
Set:不包含重复元素的Collection。
List:有顺序的collection,并且可以包含重复元素
map:可以把键(key)映射到值(value)的对象,键不能重复。
1、为什么集合类没有实现Cloneable和Serializable接口?
集合类接口指定了一组叫做元素的对象,集合类接口的每一种具体的实现类都可以选择以它自己的方式对元素进行保存和排序。有的集合类允许重复的键,有的不允许。
2、什么是迭代器?
iterator接口提供了很多对集合元素进行迭代的方法。每一个集合类都包含了可以返回迭代器实例的迭代方法。迭代器可以在迭代过程中删除底层集合的元素。
克隆或者是序列化的语义和含义是根据具体的实现相关的。因此,应该由集合类的具体实现来确定如何被克隆或者序列化。
3、Iterator和ListIterator的区别是是很么?
(1)iterator可用来遍历set和list集合,但是listiterator只能遍历list
(2)iterator对集合只能是前向遍历,listiterator可以前向也可以后向
(3)listiterator实现了iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等
4、快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
iterator的安全失败是基于对底层集合做拷贝,因此,它不受原集合上修改的影响,java.util包下面的所有集合类都是快速失败的,而 java.util.concurrent包下面的所有的类都是安全失败的。快速失败的迭代器会跑出ConcurrentModificationException异常,而安全失败的迭代器永远不会抛出这样的异常。
5、java中HashMap的工作原理是什么?
java中的hashMap是以键值对(key-value)的形式存储元素的。HashMap需要一个hash函数,它使用hashCode() 和equals()方法来向集合/从集合添加和检索元素。当调用put()方法的时候,HashMap会计算key的hash值,然后把键值对存储在集合 中合适的索引上。如果key已经存在了,value会被更新成新值。HashMap的一些重要的特性是它的容量(capacity),负载因子(load factor)和扩容极限(threshold resizing)。
6、HaseMap和HaseTable有什么区别
(1)HashMap和Hashtable都实现了Map接口,因此很多特性非常相似。但是,他们有以下不同点:
(2)HashMap允许键和值是null,而Hashtable不允许键或者值是null。
(3)Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。
(4)HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面,Hashtable提供了对键的列举(Enumeration)。
一般认为Hashtable是一个遗留的类。
7、ArrayList和LinkedList有什么区别?
ArrayList和LinkedList都实现了List接口,他们有以下的不同点:
(1)ArrayList是基于索引的数据接口,它的底层是数组。它可以以O(1)时间复杂度对元素进行随机访问。与此对应,LinkedList是以 元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。
(2)相对于ArrayList,LinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。
(3)LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。
也可以参考ArrayList vs. LinkedList。
8、如何权衡是使用无序的数组还是有序的数组?
(1)有序数组最大的好处在于查找的时间复杂度是O(log n),而无序数组是O(n)。有序数组的缺点是插入操作的时间复杂度是O(n),因为值大的元素需要往后移动来给新元素腾位置。相反,无序数组的插入时间复杂度是常量O(1)。
9、java集合类框架的最佳实践有哪些?
(1)根据应用的需要正确选择要使用的集合的类型对性能非常重要,比如:假如元素的大小是固定的,而且能事先知道,我们就应该用Array而不是ArrayList。
(2)有些集合类允许指定初始容量。因此,如果我们能估计出存储的元素的数目,我们可以设置初始容量来避免重新计算hash值或者是扩容。
(3)为了类型安全,可读性和健壮性的原因总是要使用泛型。同时,使用泛型还可以避免运行时的ClassCastException。使用JDK提供的不变类(immutable class)作为Map的键可以避免为我们自己的类实现hashCode()和equals()方法。
(4)编程的时候接口优于实现。底层的集合实际上是空的情况下,返回长度是0的集合或者是数组,不要返回null。
10、HashSet和TreeSet有什么区别?
(1)HashSet是由一个hash表来实现的,因此,它的元素是无序的。add(),remove(),contains()方法的时间复杂度是O(1)。
(2)TreeSet是由一个树形的结构来实现的,它里面的元素是有序的。因此,add(),remove(),contains()方法的时间复杂度是O(logn)。
略有不足,欢迎补充。
网友评论