Stack Overflow上关于Java Collections的几个常见问题
来源:互联网 发布:mysql 5.5.23.tar.gz 编辑:程序博客网 时间:2024/04/29 04:12
下面列出Stack Overflow上最常见的几个关于Java Collections的问题并给出答案。
1. 什么时候用LinkedList,什么时候用ArrayList?
ArrayList
是使用数组实现的list,本质上就是数组。ArrayList中的元素可以通过索引随机获取一个元素。但是如果该数组已满,当添加新元素时需要分配一个新的数组然后将原来数组的元素移动过去,需要O(n)的时间复杂度。添加或删除一个元素需要移动数组中的其他元素。这是ArrayList最大的缺点。
LinkedList
是一个双向链表。因此,当需要获取list中某个元素,需要从头到尾遍历list。另一方面,在链表中添加或删除元素很快,只需要O(1)的时间复杂度。从空间上来说,在链表中一个节点需要两个额外的指针来指向它的previous和next节点。
总结:
从时间复杂度来说,如果对list增加或删除操作较多,优先用LinkedList;如果查询操作较多,优先用ArrayList。
从空间复杂度来说,LinkedList会占用较多空间。
2. 如何边遍历边移除Collection中的元素
边遍历边修改Collection的唯一正确方式是使用Iterator.remove
方法,如下:
Iterator<Integer> it = list.iterator;while(it.hasNext){ // do something it.remove;}
一种最常见的错误代码如下:
for(Integer i : list){ list.remove(i)}
运行以上错误代码会报ConcurrentModificationException
异常。这是因为当使用foreach
(for(Integer i : list))语句时,会自动生成一个iterator来遍历该list,但同时该list正在被Iterator.remove
修改。在Java中,一般不允许一个线程在遍历collection时另一个线程在修改它。
3. 如何将List转化成int?
很多人可能认为只需用List.toArray
即可,其实不然。List.toArray方法只可能得到Integer,无法得到int。
最简单的方法是使用Apache Commons Lang
库中的ArrayUtils
。
int array = ArrayUtils.toPrimitive(list.toArray(new Integer[0]));
在JDK中,没有捷径。需要注意的是,不能直接使用List.toArray
,因为这样会将List转化成Integer而不是int。正确的做法如下:
int array = new int[list.size()];for(int i = 0; i < list.size; i++){ array[i] = list.get(i);}
4. 如何将int转化成List?
同上,很多人以为只需用Arrays.asList
即可,其实不然。因为不能以int作为该方法的参数,要的话也只能是Integer。
关于Arrays.asList
方法有如下特性:
- 1.该方法对于基本数据类型的数组支持并不好,当数组是基本数据类型时不建议使用
- 2.当使用asList方法时,数组就和列表链接在一起了。当更新其中之一时,另一个将自动获得更新。因为asList获得的List实际引用的就是数组 注意:仅仅针对对象数组类型,基本数据类型数组不具备该特性。
- 3.asList得到的数组是的没有add和remove方法的。因为asList返回的List是Arrays中的内部类,而该类并没有定义add和remove方法。
那么如何将int转化成List呢?
还是得自己实现:
int array = {1,2,3,4,5};List<Integer> list = new ArrayList<Integer>;for(int i: array) { list.add(i);}
5. 过滤一个Collection最好的方法是什么?
如过滤掉list中大于5的整数。
Iterator<Integer> it = list.iterator;while(it.hasNext){ int i = it.next; if(i > 5) { //过滤掉大于5的整数 it.remove; }}
6. 将List转化成Set最简单的方法?
有两种方法,取决于你怎么要怎么定义两个元素相等。第一种方法是将list放入HashSet
里,该方法元素是否相等是通过它们的hashCode来比较的。如果需要自己定义比较的方法,需要用TreeSet
。
Set<Integer> set = new HashSet<Integer>(list);
Set<Integer> set = new TreeSet<Integer>(aComparator);set.addAll(list);
7. 如何删除ArrayList中重复的元素?
如果不关心元素在ArrayList中的顺序,可以将list放入set中来删除重复元素,然后在放回list。
Set<Integer> set = new HashSet<Integer>(list);list.clear;list.addAll(set);
如果关心元素在ArrayList中的顺序,可以用LinkedHashSet
。
8. 有序的collection
Java里有很多方法来维持一个collection有序。有的需要实现Comparable接口,有的需要自己指定Comparator。
Collections.sort
可以用来对list排序。该排序是稳定的,并且可以保证nlog(n)的性能。PriorityQueue
提供排序的队列。PriorityQueue
和Collections.sort
的区别是,PriorityQueue
动态维护一个有序的队列(每添加或删除一个元素就会重新排序),但是只能获队列中的头元素。- 如果collection中没有重复的元素,
TreeSet
是另一个选择。跟PriorityQueue
一样的是,TreeSet
也动态维护一个有序的集合。可以从TreeSet
中获取最大和最小的元素。
总结:Collections.sort
提供一个一次排序的list。PriorityQueue
和TreeSet
动态维护排序的collection。
9. 拷贝list
有两种方法可以用来拷贝list。一种是使用ArrayList
构造器。
ArrayList<Integer> dstList = new ArrayList<Integer>(srcList);
另一种是使用Collections.copy
。
ArrayList<Integer> dstList = new ArrayList<Integer>(srcList.size);Collections.copy(dstList, srcList);
需要注意的是,使用该方法的话目标list至少跟源list长度一样长。否则会报IndexOutOfBoundsException
异常。
另外有两点需要注意:
- 两种方法都是浅拷贝
Collections.copy
方法的两个参数必须都是list,而ArrayList
方法参数只要是collection即可,因此ArrayList
方法更通用。
扫一扫关注公众号:FullStackPlan获取更多干货哦~
本文为头条号作者发布,不代表今日头条立场。
- Stack Overflow上关于Java Collections的几个常见问题
- 关于 Java Collections 的几个常见问题
- 关于Java Collections的几个常见问题
- 有关Java Collections的几个常见问题
- Java Collections的常见问题
- 关于 stack overflow 的一点思考 chkstk
- 在stack overflow上看到的关于tornado-RESTful的讨论
- collections - Blackbery JDE ArrayList? - Stack Overflow
- 几个java的常见问题
- stack overflow 的解决
- stack overflow的问题
- stack overflow的 问题
- Stack Overflow上提到的最多书籍的排行
- 关于PayPal的几个常见问题
- 关于apache的几个常见问题
- 关于字符串的几个常见问题
- 关于堆溢出(Stack overflow)问题的解决
- 关于vs未处理的异常: 0xC00000FD: Stack overflow
- 自动筛选的逻辑(1)-筛选按钮
- 你好,我是小程序
- 原来Spring定时器可以这样注入service
- Unity中GameObject发送消息
- oracle 环境搭建
- Stack Overflow上关于Java Collections的几个常见问题
- 自动筛选的逻辑(2)-自助
- SpringMVC的数据校验
- Java基础工具类杂谈
- 自动筛选的逻辑(3)-实现隐藏
- jquery 对象 json spring后台接收
- 算法训练 最长字符串
- 自动筛选的逻辑(4)-对可见数据的处理
- 如何用FTP软件上传网站文件