伙伴们注意了!
小编在这里给大家送上关注福利:
搜索微信号“suxueJava”即可领取小编精心准备的资料一份!
以下是在Stackoverflow上询问和讨论的Java集合最流行的问题。
在查看这些问题之前,最好先查看类层次图。
1. 什么时候使用LinkedList而不是ArrayList?
ArrayList本质上是一个数组。
它的元素可以通过索引直接访问。
但如果数组已满,则需要一个更大的新数组来分配和移动所有元素到新数组将花费O(n)时间。
添加或删除元素还需要移动数组中的现有元素。
这可能是使用ArrayList的最大缺点。
LinkedList是一个双链表。
因此,要访问中间的元素,必须从列表的开头进行搜索。
另一方面,在LinkedList中添加和删除元素更快,因为它只在本地更改列表。
综上所述,时间复杂度比较最坏的情况如下:
尽管运行时间很长,但是对于大型列表来说,内存的使用也应该被考虑在内。在LinkedList中,每个节点至少需要两个额外的指针来链接上一个和下一个节点;而在ArrayList中,只需要一个元素数组。
2. 在迭代集合时删除元素的有效等效方法
在迭代时修改集合的惟一正确方法是使用Iterator.remove()。例如,
最常见的错误代码是
通过运行上面的代码,您将获得一个ConcurrentModificationException异常。
这是因为已经生成了一个迭代器(在for语句中)来遍历列表,但同时list被iterator .remove()更改。
在Java中,“通常不允许一个线程在另一个线程遍历集合时修改该集合”。
3.如何将List转换为int[]?
最简单的方法可能是在Apache Commons Lang库中使用ArrayUtils。
在JDK中,没有捷径。
注意,您不能使用List. toarray(),因为这会将List转换为Integer[]。
正确的方法如下,
4.如何将int[]转换为List?
最简单的方法可能仍然是在Apache Commons Lang库中使用ArrayUtils,如下所示。
在JDK中,也没有捷径。
5.筛选集合的最佳方法是什么?
同样,您可以使用第三方包,如Guava或Apache Commons Lang来完成此功能。
两者都提供了filter()方法(在番石榴的Collections2和Apache的CollectionUtils中)。
filter()方法将返回与给定谓词匹配的元素。
在JDK中,事情变得更加困难。
好消息是,在Java 8中,将添加谓词。
但是现在您必须使用Iterator来遍历整个集合。
当然,您可以通过引入新的接口谓词来模仿番石榴和Apache的做法。
这可能也是大多数高级开发人员将要做的事情。
然后我们可以使用下面的代码来过滤一个集合:
6. 将列表转换为集合的最简单方法?
有两种方法可以这样做,这取决于您希望如何定义等号。第一部分代码将一个列表放入一个HashSet中。
然后,重复主要由hashCode()标识。在大多数情况下,这是可行的。但是如果您需要指定比较的方式,最好使用第二段代码,其中可以定义自己的比较器。
7. 如何从ArrayList中删除重复的元素?
这个问题和上面的问题有很大的关系。
如果您不关心ArrayList中元素的顺序,一个聪明的方法是将列表放入一个集合中以删除重复,然后将其移回列表中。下面是代码
如果您确实关心排序,那么可以通过将一个列表放入标准JDK中的Linkedhashset中来保留顺序。
8.分类收集
有几种方法可以在Java中维护排序的集合。它们都以自然顺序或通过指定的比较器提供了一个集合。通过自然排序,您还需要在元素中实现可比较的接口。
collections.sort()可以对列表进行排序。正如JavaDoc中指定的那样,这种排序是稳定的,并保证n个日志(n)的性能。
PriorityQueue提供有序队列。priorityQueue和collections.sort()的区别在于priorityQueue始终维护一个订单队列,但只能从队列中获取head元素。您不能随机访问它的元素,如priorityqueue.get(4)。
如果集合中没有重复项,则TreeSet是另一个选择。与PriorityQueue相同,它始终维护有序集。你可以从树集中得到最低和最高的元素。但您仍然不能随机访问它的元素。
总之,collections.sort()提供了一个一次性的有序列表。PriorityQueue和Treeset始终维护有序的集合,而不需要对元素进行索引访问。
9.collections.emptylist()与新实例
同样的问题也适用于emptymap()和emptyset()。
两个方法都返回空列表,但collections.empty list()返回不可变的列表。这意味着您不能将新元素添加到“空”列表中。在后台,每次调用collections.empty list()实际上不会创建空列表的新实例。相反,它将重用现有的空实例。如果你对设计模式很熟悉,你应该知道我的意思。因此,如果经常打电话,这将给您带来更好的性能。
10 Collections.copy
有两种方法可以将源列表复制到目标列表。一种方法是使用arraylist构造函数
另一个是使用collections.copy()(如下所示)。注意第一行,我们分配的列表至少与源列表一样长,因为在集合的javadoc中,它表示目标列表必须至少与源列表一样长。
这两种方法都是肤浅的复制。那么这两种方法有什么区别呢?
首先,collections.copy()不会重新分配dstlist的容量,即使dstlist没有足够的空间来包含所有srcList元素。相反,它将抛出indexoutofboundsException。人们可能会质疑它是否有任何好处。一个原因是它保证了方法在线性时间内运行。另外,当您希望重用数组而不是在arraylist的构造函数中分配新内存时,它也非常适合。
collections.copy()只能接受list作为源和目标,而arraylist接受collection作为参数,因此更通用。