Java Collections
4.10 ArrayList和LinkedList之间的区别
ArrayList和LinkedList都实现了List接口,但是他们有以下方面的不同:
ArrayList是基于Array的,带有index的数据结构。它可以随机读取里面的元素,操作的时间复杂度为O(1)。另一方面,LindedList把数据作为list的元素,每一个元素与它的前一个和后一个元素关联,搜索的时间复杂度为O(n)。
对于插入操作,LinkedList的添加、删除操作比ArrayList是更快的。因为LinkedList没有重新调整大小,或者因插入位置任意而需要的更新索引。
LinkedList比ArrayList会消耗更多的内存空间,因为LinkedList中的每个节点都存储了两个引用,一个指向前面的元素,一个指向后面的元素。
4.11 Comparable和Comparator接口是什么?列举他们的不同点
java提供了Comparable接口,其中只有一个compareTo方法。这个方法会比较两个对象,为了给这两者一个顺序。明确地,它返回一个负数、零或一个正数,来表示输入的对象是否小于、等于或大于当前对象。
java也提供了Comparator接口,其中有两个方法,compare和equals。
compare方法,是比较两个输入参数,然后给出两者的一个顺序。它返回一个负数、零或正数,来表示第一个参数是否小于、等于或大于第二个参数。
equals方法需要一个对象作为参数,然后检测输入是否和被比较的数相等。它只在对象是被比较数,或者它代表了被比较数的相同的顺序。
4.12 什么是优先队列
优先队列是一个极大的队列,基于一个优先堆然后元素是按自然顺序排列。在创建的时候,我们可以提供一个用于排序的Comparator。优先队里不允许null值、不能提供自然排序的对象和comparator无关的对象。最后,java的优先队列不是线程安全的,它需要O(log(n))时间来完成入队或出队操作。
4.13 了解大O符号吗?能给出一些和不同数据结构有关的例子吗?
大O符号简单的描述了一个算法的衡量或表现,在最差的场景下,会作为一个数据结构中的元素增加。大O符号可以被用来描述其他的行为,例如内存消耗。因为结合累实际就是数据结构,我们通常用大O 符号来选择最佳的实现,基于时间、内存和性能。大O符号对于大数据量的性能是一个好的指标。
4.14 选用有序数组和无序数组的权衡
有序数组的主要优点是,搜索时间为O(log n),相比较于无序数组而言,搜索时间为O (n)。有序数组的缺点是插入操作的时间复杂度为O(n),因为较大值必须移动来为新的元素腾出位置。相反,无序数组的插入的时间是定值O(1)。
4.15 java collection框架相关的最佳实践有哪些?
基于应用的需要,选择正确的collection类型对于性能非常重要。例如,如果指的元素的大小和先验,我们应该用Array代替ArrayList。
一些collection类允许我们定义他们的初始化容量。因此,如果我们对被保存的元素个数有一个评估,我们可以用它来避免重新hash和重新调整大小。
通常用Generics来保证类型安全、可读性和健壮性。同事,适用Generics可以避免在运行期间出现ClassCastException。
4.16 Enumeration和Iterator接口的区别?
Enumeration是Interator的两倍快,同时还节省更多的内存。同事,Iterator比Enumeration更安全,因为其他的线程不能在遍历的时候修改colletion的对象。另外,Iterator允许调用者移除基础的collection里的元素,这在Enumeration里面是不允许的。
4.17 HashSet和TreeSet的区别?
HashSet用hashtable来实现的,因此它的元素不是有序的。HashSet的添加、移除和contains方法,都是O(1)的时间复杂度。另外,TreeSet是用树的机构实现的。TreeSet的元素是分类的,因此它的添加、移除和contains方法有时间复杂度O(logn)。