集合框架
List
1.List是java集合框架种最常见的一个集合接口,直接从Collection继承而来;
2.List集合是一个有序集合(内部的元素顺序按照添加顺序存储);
3.List接口中包含几个常用的实现类:
ArrayList:数组列表,基于动态数组的实现;
LinkedList:链表,基于链表的表现;
Vector:数组列表,基于动态数组的实现;
ArrayList、LinkedList、Vector的区别
ArrayList:是基于动态数组的实现,内部的实现基于数组完成,因此在进行元素查找的时候只需要根据元素的索引即可快速找到,但是在更新时或者插入时,由于数组结构是连续的,元素一旦向中间插入,则后续的元素需要整体后移,效率低。ArrayList是线程不同步的实现,在多线程并发操作时不能保证数据的安全,但是效率高;另外ArrayList在进行容量扩充是增长原来的1.5倍(增长原来长度的一半);线程安全的ArrayList可以使用java.util.concurrent.CopyOnWriteArrayList
LinkedList:是基于双链表的实现,集合中元素的组织是通过元素的首尾指针连接,在进行数据修改时只需要改动指针的指向即可轻松实现,但是在进行查询的时候,需要从链表头依次搜索,因此修改时,效率较低.
Vector:和ArrayList一样也是基于动态数组的实现,但是Vector是老式JDK(JDK1.0)中的一个动态数组类,提供的是一些线程安全(线程同步)的集合操作,因此,在多线程并发时,对数据的安全性会有一定保障,但是带来的影响就是效率低;另外Vector当容量不足时会在原来长度的基础上增长一倍(ArrayList增长一半)
ArryList实现
public class ArrayListDemo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(10);
list.add(20);
list.add(30);
list.add(40);
list.add(50);
list.add(60);
List<Integer> list2 = new ArrayList<>();
list2.add(100);
list2.add(200);
list.addAll(list2);
System.out.println(list.contains(100));
// for (Integer integer : list) {
// list.remove(integer);
// }
//不允许在对集合遍历时调用集合的remove方法更改元素,会抛出一ConcurrentModificationException
//如果需要在遍历时删除,因该调用通过集合获取的迭代器对象自生的remove方可更改
Iterator<Integer> it = list.iterator();
while(it.hasNext()){
int i = it.next();
//remove前要确保next()获取过元素,否则会出现IllegalStateException
it.remove();
}
}
}
Set
Collection接口还提供了另一个子接口Set,Set是一个无序集合,元素的存储顺序不是按照添加顺序存储(具体存储顺序跟使用的实现类有关);因为元素的存储是无序的,因此无法像List一样通过索引获取元素,所以对于Set集合中元素的获取只能通过迭代器进行迭代;另外Set集合中不允许出现重复的元素(不允许存在e1.equals(e2)),实际上是后出现的元素会覆盖原来存在的。
Set集合有两个常见的实现:
- HashSet:基于散列算法(Hashtable)实现的元素存储顺序
- TreeSet:基于二叉树中红黑树的实现,元素的排序方式需要通过实现Comparable或者Comparator接口完成
HashSet和TreeSet的区别
HashSet:基于Hash表实现的元素存储,内部元素的排序按照hash表中的地址进行排序,内部允许null值存在,但是不允许重复的元素,如果一旦出现重复的元素(此时hash值是已经存在的情况,不会将新的元素存储)。
TreeSet:基于树的实现,内部元素的排序需要通过提供排序比较器(Comparable,Comparator)进行实现;内部的元素必须是Comparable实现类(或者在创建TreeSet对象时提供Comparator比较器),并且由于比较器内部会使用到集合中的元素,因此元素不允许为null(会导致NullPointerException).