List集合
1.1List集合概述
List
是所有有序集合的顶层接口,List
的实现集合允许元素重复(有相同的equals,hashcode
),并且元素的存储是有序的(存储的顺序是按照添加的顺序),典型的实现类:java.util.ArrayList
;
List的常见实现类:
ArrayList
LinkedList
Vector
1.1.1List
接口的常见方法 (除继承Collection的方法之外)
-
add(int index,E e)
:向指定的位置插入元素 -
addAll(int index,Collection<? extends E> c)
:向指定的位置插入子集合 -
get(int index)
:获取指定位置的元素 -
indexOf(Object obj)
:返回集合中指定元素第一次出现的索引 -
lastIndexOf(Object obj)
:返回集合中指定元素最后一次出现的索引 -
listIterator()
:获取一个可以进行上下迭代的列表迭代器 -
subList(int fromIndex,int toIndex)
:从集合的fromIndex
(包含)位开始截取,截取到toIndex
(不含),并返回子集合 -
remove(index i)
:根据索引删除元素
1.2ArrayList
ArrayList
是List
中最常用的一个实现类,其内部是基于动态的Object数组实现的,允许存储重复的元素,元素的顺序按照添加元素的顺序来的,并且扩容的时候是每次扩容为原来的1.5倍,并且ArrayList
是一个非线程安全的集合实现,即在多线程并发环境下可能造成结果不一致的情况出现,因此多线程的环境中使用时,一啊不能会选择加锁。
ArrayList
常用方法
List<String> list = new ArrayList<>();
//添加单个元素
list.add("Hello");
//在指定的索引添加元素
list.add(1,"world");
List<String> list1 = Arrays.asList("work","time");
//添加一个子集合
list.addAll(list1);
list.addAll(0,list1);
System.out.println(list);
//返回集合大小
System.out.println(list.size());
//删除指定的元素
list.remove("world");
//删除指定索引的元素
list.remove(0);
//截取指定索引范围的元素[2,3)
System.out.println(list.subList(2, 3));
//判断结合是否为空
System.out.println(list.isEmpty());
//判断元素是否在集合中
System.out.println(list.contains("world"));
//清空集合中的元素
list.clear();
1.3LinkedList
LinkedList
是List
接口的另一个常见实现类,是基于链表(双向链表)实现的,其实现了List
接口和Deque
(双端队列),在对元素进行添加时,只需要修改元素首指针即可,因此在集合中对元素进行增删操作时效率较高,但是在进行查询时,因为没有类似数组的索引,每次搜索都需要从链表头开始,所以查询的时候效率较低。
LinkedList
除具有List
中常见的方法之外还具有以下常见方法:
LinkedList<Integer> list = new LinkedList<>();
list.add(20);
list.add(30);
list.add(40);
list.add(50);
list.add(60);
//获取集合大小
System.out.println(list.size());//5
//返回列表中国指定位置的元素
System.out.println(list.get(3));//50
//实现队列的方法
list.addFirst(10);
list.addLast(70);
//获取集合中第一个元素
System.out.println(list.getFirst());//10
//获取集合中最后一个元素
System.out.println(list.getLast());//70
//去除栈顶元素,
list.pop();
System.out.println(list);//[20, 30, 40, 50, 60, 70]
//返回栈顶元素,但是不删除
Integer peek = list.
ArrayList
和LinkedList
区别?
- 从实现原理来看:
ArrayList
是基于动态数组的实现LinkedList
是基于双向链表的实现
- 从数据操作来看:
ArrayList
可以通过索引访问元素,查询效率较高,但是对于元素的增删操作,是基于数组拷贝完成的,所以效率比较低。linkedList
直接通过首尾指针与各个节点相连,在对元素进行增删操作时只需要修改指针的指向即可,效率较高。但是在进行查询时,每次都要从头逐个进行查找,效率低。
- 总结:
- 查询多使用
ArrayList
。 - 增删操作多使用
LinkedList
。
- 查询多使用
1.4Vector
java.util.Vector
是在JDK1.0就已经存在的一个集合实现,内部是基于动态数组的实现,提供的对数据操作的方法都是线程安全synchronized
,因此在多线程并发操作集合时数据的安全性能够得到保障,但是效率也会随机受影响。在容量扩充方面Vector
当容量不足时会扩展为原来的2倍大小。另外从JDK1.2开始Vector
被设置为从List
接口实现(被集合收编)。