关于Java集合最被关注的10 个问题

简介:  下面是stackoverflow关于Java集合方面讨论最多的几个问题,在这里整理出来供大家参考。 1.关于LinkList和ArrayList ArrayList:内部实现是个数组,其中的元素可以通过index获取。但是,如果一个数组满了的话,我们就必须重新分配一个更大的数组然后把所有元素移动到这个新数组,其时间复杂度为O(n)。添加或删除一个元素时也需要移动数组中的其它
 下面是stackoverflow关于Java集合方面讨论最多的几个问题,在这里整理出来供大家参考。

1.关于LinkList和ArrayList
  • ArrayList:内部实现是个数组,其中的元素可以通过index获取。但是,如果一个数组满了的话,我们就必须重新分配一个更大的数组然后把所有元素移动到这个新数组,其时间复杂度为O(n)。添加或删除一个元素时也需要移动数组中的其它元素。这就是ArrayList的缺点。
  • LinkedList:是一个双向链表。因此如果我们要获取中间元素的话,我们就需要从头开始遍历;另一方面,添加或删除一个元素就变得很简单,因为只需要对这个链表本身操作即可。
    总的来说,最坏的情况下两者时间复杂度的对比如下:
                   | Arraylist | LinkedList
 ------------------------------------------
 get(index)        |    O(1)   |   O(n)
 add(E)            |    O(n)   |   O(1)
 add(E, index)     |    O(n)   |   O(n)
 remove(index)     |    O(n)   |   O(n)
 Iterator.remove() |    O(n)   |   O(1)
 Iterator.add(E)   |    O(n)   |   O(1)
    除了考虑时间复杂度之外,当List比较大时,空间复杂度也不可忽略:
  • LinkList:每个节点还需要额外的两个指针,分别指向前一个节点和下一个节点
  • ArrayList:只需要一个数组

2.最有效移除集合元素的方式
    唯一正确的移除集合元素的方式就是使用Iterator.remove()方法:
Iterator<Integer> itr = list.iterator();
while(itr.hasNext()) {
   // do something
   itr.remove();
}

  下面这种处理方式是错误的,会报出这么一个异常:ConcurrentModificationException
for(Integer i: list) {
  list.remove(i);
}
3.如何将一个List转换成一个int[] 数组?
     最简单的方式就是使用Apache Commons Lang工具包下的ArrayUtils
int[] array = ArrayUtils.toPrimitive(list.toArray(new Integer[0]));
如果用jdk的话是没有捷径的,注意我们不能使用List.toArray()方法,因为这样得到的是Integer[],正确的方法应该是:
int[] array = new int[list.size()];
for(int i=0; i < list.size(); i++) {
  array[i] = list.get(i);
}

4.如何将int[] 转换成List?
     和上面类似,我们可以使用ArrayUtils工具类:
List list = Arrays.asList(ArrayUtils.toObject(array));
或者依然没有捷径:
int[] array = {1,2,3,4,5};
List<Integer> list = new ArrayList<Integer>();
for(int i: array) {
  list.add(i);
}
5.最好的过滤集合的方法?  
    当然,最方便最好的方式就是使用第三方jar包,比如 Guava or Apache Commons Lang ,这两者都提供了filter()方法。在jdk中,事情就变得没那么简单了(不过Java8已经支持Predicate了),但是在Java8之前,比较通常的方式是我们必须遍历集合中的所有元素:
 
   
Iterator<Integer> itr = list.iterator();
while(itr.hasNext()) {
   int i = itr.next();
   if (i > 5) { // filter all ints bigger than 5
      itr.remove();
   }
}
但是我们可以模拟 Guava Apache Commons Lang,通过引入一个新的 Predicate接口,这是很多高级工程师的方法:
public interface Predicate<T> {
   boolean test(T o);
}
 
public static <T> void filter(Collection<T> collection, Predicate<T> predicate) {
    if ((collection != null) && (predicate != null)) {
       Iterator<T> itr = collection.iterator();
          while(itr.hasNext()) {
            T obj = itr.next();
            if (!predicate.test(obj)) {
               itr.remove();
            }
        }
    }
}
filter(list, new Predicate<Integer>() {
    public boolean test(Integer i) { 
       return i <= 5; 
    }
});
6.把List转换成Set的最简单的方式有两种方式:
Set<Integer> set = new HashSet<Integer>(list);
Set<Integer> set = new TreeSet<Integer>(aComparator);
set.addAll(list);
7.如何移除ArrayList中的重复元素  
    和上面方法类似,如果不关心顺序的话:
ArrayList** list = ... // initial a list with duplicate elements
Set<Integer> set = new HashSet<Integer>(list);
list.clear();
list.addAll(set);
如果关心顺序,把上面那个HashSet换成LinkedHashSet即可。
8.给集合排序    
   给集合排序的实现方法有很多种
	1.Collections.sort():进行一次排序
	2.PriorityQueue :始终保持队列的顺序,但是只能从队列的头获取元素
	3.TreeSet:始终保持队列的顺序,元素不重复,你可以从最顶端或最低端获取元素,但也不能随机获取元素
9.Collections.emptyList() vs new Instance     
    上面两个方法都会返回空的List,但是Collections.emptyList()返回的List是不可变的,每次方法调用不会重新创建一个实例,而是复用原来的实例(即单例模式),所以这样效率会高些。
10.Collections.copy     
    有两种方式复制一个List,第一种:
ArrayList<Integer> dstList = new ArrayList<Integer>(srcList);
第二种是利用Collections.copy()方法:
ArrayList<Integer> dstList = new ArrayList<Integer>(srcList.size());
Collections.copy(dstList, srcList);
那两者有何区别呢?  
    如果目标集合(dstList)小于源集合,使用Collections.copy()会抛出IndexOutOfBoundsException,那它有什么好处呢?首先它保证运行效率和集合大小线性相关,第二就是可以实现集合的重用。
 
目录
相关文章
|
7月前
|
存储 安全 Java
java集合框架及其特点(List、Set、Queue、Map)
java集合框架及其特点(List、Set、Queue、Map)
|
4月前
|
存储 安全 Java
【Java集合类面试二十五】、有哪些线程安全的List?
线程安全的List包括Vector、Collections.SynchronizedList和CopyOnWriteArrayList,其中CopyOnWriteArrayList通过复制底层数组实现写操作,提供了最优的线程安全性能。
|
4月前
|
Java
【Java集合类面试二十三】、List和Set有什么区别?
List和Set的主要区别在于List是一个有序且允许元素重复的集合,而Set是一个无序且元素不重复的集合。
|
2月前
|
安全 Java 程序员
深入Java集合框架:解密List的Fail-Fast与Fail-Safe机制
本文介绍了 Java 中 List 的遍历和删除操作,重点讨论了快速失败(fail-fast)和安全失败(fail-safe)机制。通过普通 for 循环、迭代器和 foreach 循环的对比,详细解释了各种方法的优缺点及适用场景,特别是在多线程环境下的表现。最后推荐了适合高并发场景的 fail-safe 容器,如 CopyOnWriteArrayList 和 ConcurrentHashMap。
69 5
|
7月前
|
Java 程序员
Java集合框架:List、Set、Map类型及泛型详解
Java集合框架:List、Set、Map类型及泛型详解
106 0
|
4月前
|
存储 安全 Java
java集合框架复习----(2)List
这篇文章是关于Java集合框架中List集合的详细复习,包括List的特点、常用方法、迭代器的使用,以及ArrayList、Vector和LinkedList三种实现类的比较和泛型在Java中的使用示例。
java集合框架复习----(2)List
|
4月前
|
存储 安全 Java
java集合框架复习----(4)Map、List、set
这篇文章是Java集合框架的复习总结,重点介绍了Map集合的特点和HashMap的使用,以及Collections工具类的使用示例,同时回顾了List、Set和Map集合的概念和特点,以及Collection工具类的作用。
java集合框架复习----(4)Map、List、set
|
5月前
|
存储 安全 Java
详解Java中集合的List接口实现的ArrayList方法 | Set接口实现的HashSet方法
详解Java中集合的List接口实现的ArrayList方法 | Set接口实现的HashSet方法
|
6月前
|
存储 Java 索引
告别Java集合小白!一文读懂List的精髓
【6月更文挑战第17天】Java中的List接口作为有序集合,允许存储和操作有序元素,支持重复值。ArrayList和LinkedList是常见实现类:ArrayList基于数组,适合快速访问但插入删除慢;LinkedList基于链表,插入删除快但访问慢。了解其核心概念、方法及泛型使用,能提升编程效率和代码质量。示例代码展示了添加和访问元素。通过深入学习,可以更好地掌握List的高级用法。
72 1
|
6月前
|
存储 安全 Java
Java集合详解:Set, Map, Vector, List的对比与联系
Java集合框架核心包括List、Set、Map和Vector。List允许重复元素,如ArrayList(适合读取)和LinkedList(适合插入删除)。Set不允许重复,有HashSet(无序)和TreeSet(排序)。Map存储键值对,HashMap(无序)和TreeMap(排序)。Vector是线程安全的ArrayList替代品,但在多线程环境下使用。选择集合类型应根据应用场景,如有序、无序、键值对需求及线程安全考虑。