Arraylist
概述
List
接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括null
在内的所有元素。除了实现
List
接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。(此类大致上等同于Vector
类,除了此类是不同步的。)
数据结构: 数据的存储方式
和集合相关的数据结构: 数组 栈 队列 链表 哈希表 二叉树
主要是观察集合的add方法
特点
- 底层数据结构是数组
- 增加和删除的效率低,查询和修改的效率高
- 能够存储 null 值
- 线程不安全,效率高 可以通过 Collections.synchronizedList();变安全
- 有索引,能够方便检索
- 元素可重复,我们自己可以通过 选择排序去重复
- 不可以排序,但是可以通过 Collections.sort();方法排序
去重复:
- 1.创建一个新集合
// 1.创建一个新的集合
Collection c2 = new ArrayList();
// 2.遍历旧集合
for (Object oj : c) {
// 3.判断新集合中是否存在这个元素
if (!c2.contains(oj)) {
// 4.如果新集合中不存在该元素就存储到集合中
c2.add(oj);
}
}
for (Object oj : c2) {
System.out.println(object);
}
- 2.选择排序思想去重复
for (int i = 0; i < a.size(); i++) {
for (int j = i+1; j < a.size(); j++) {
if (a.get(i).equals(a.get(j))) {
a.remove(j);
j--;
}
}
}
for (Object object : c) {
System.out.println(object);
}
如何排序?
- Collections.sort(list);
如何变安全?
- Collections.synchronizedList(list);
List接口
概述
有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
Collection将集合划分为两大类:**
- List集合
- Set集合
List接口的特点
-
有序【存储有序】
-
可重复
-
可以存储
null
值 -
部分子集合线程安全,部分不安全 例如
ArrayList
和Vector
-
有索引,针对每个元素能够方便地查询和修改
-
判断元素是否重复依赖于
equals
方法 a. 如果元素是系统类,不需要重写
equals
方法 b. 如果是自定义类,就需要我们按需求重写
equals
方法
List接口的常用方法
1.添加功能
- boolean add(Object obj)
- boolean addAll(Collection c)
- void add(int index, E element)
- boolean addAll(int index, Collection<? extends E> c)
2.删除功能
- void clear()
- boolean remove(Object o)
- boolean removeAll(Collection<?> c)
- Object remove(int index)
- boolean remove(Object o)
3.修改功能
- Object set(int index, E element)
4.遍历功能
- Object[] toArray()
- Iterator iterator()
- T[] toArray(T[] a)
- ListIterator listIterator()
- ListIterator listIterator(int index)
5.判断功能
- boolean contains(Object o)
- boolean containsAll(Collection<?> c)
- boolean isEmpty()
6.其他功能
- boolean retainAll(Collection<?> c)
7.获取集合长度的功能
- int size()
8.获取功能
- int indexOf(Object o)
- Object get(int index)
- int lastIndexOf(Object o)
- List subList(int fromIndex, int toIndex)
集合的遍历方式:
1.toArray
Object[] objects = vector.toArray();
for (Object object : objects) {
System.out.println(object);
}
2.Iterator
Iterator it = vector.iterator();
while (it.hasNext()) {
Object object = it.next();
System.out.println(object);
}
for (Iterator iterator = vector.iterator();iterator.hasNext(); ) {
Object object = iterator.next();
System.out.println(object);
}
3.foreach
for (Object object : vector) {
System.out.println(object);
}
4.普通for
for (int i = 0; i < vector.size(); i++) {
System.out.println(vector.get(i));
}
5.ListIterator
1.列表迭代器 正向遍历
ListIterator listIterator = vector.listIterator();
while (listIterator.hasNext()) {
System.out.println(listIterator.next());
}
2.列表迭代器 逆向遍历
for (ListIterator lit = vector.listIterator(vector.size()); lit.hasPrevious();) {
System.out.println(lit.previous());
}
Vector所特有的遍历方式 旧版迭代
Enumeration elements = vector.elements();
while (elements.hasMoreElements()) {
System.out.println(elements.nextElement());
}
Vector
类似于ArrayList,底层数据结构是数组,插入和移除性能较差,线程安全,效率低。
特点
- 底层数据结构是数组
- 有索引,能够方便检索
- 增加和删除的效率低,查询和修改的效率高
- 线程安全,效率低
- 能够存储 null 值
- 元素可重复【我们自己可以通过选择排序思想去除重复元素】
- 不可以排序,但是可以通过 Collections.sort();方法排序
Vector类特有功能
1.public void addElement(E obj) 添加元素 obj 到集合中
2.public E elementAt(int index) 获取指定索引 index 的元素
3.public Enumeration elements() 使用 Enumeration 迭代器遍历集合中的元素
ArrayList和Vector的区别?
1) Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。
2) 当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。
LinkedList
特点
- 1.底层数据结构是链表
- 2.链表的特点有序,查询和修改效率低,增加和删除效率高
- 3.可以存储null值
- 4.线程不安全
- 5.允许重复
- 6.不可排序
特有方法:
- void addFirst(E e)
- void addLast(E e)
- E getFirst()
- E getLast()
- E removeFirst()
- E removeLast()
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.add("apple1");
list.add("banana2");
list.add("pear3");
list.add("orange4");
list.add("pear5");
list.add("pear6");
list.add("banana7");
list.addFirst("head");
list.addLast("tail");
System.out.println(list);
System.out.println("getFirst():" + list.getFirst());
System.out.println("getLast():" + list.getLast());
System.out.println(list);
System.out.println("removeFirst:" + list.removeFirst());
System.out.println("removeLast:" + list.removeLast());
System.out.println(list);
}
}
Stack类
概述
Stack
类表示后进先出(LIFO)的对象堆栈。它通过五个操作对类Vector
进行了扩展 ,允许将向量视为堆栈。它提供了通常的push
和pop
操作,以及取堆栈顶点的peek
方法、测试堆栈是否为空的empty
方法、在堆栈中查找项并确定到堆栈顶距离的search
方法。
特点
- 基于栈结构的集合,先进后出
Stack
类是Vector
类的子类,所以该类也是线程安全的,效率低,建议使用Deque
接口的实现类
方法:
boolean empty()
测试堆栈是否为空。
E peek()
查看堆栈顶部的对象,但不从堆栈中移除它。
E pop()
移除堆栈顶部的对象,并作为此函数的值返回该对象。
E push(E item)
把项压入堆栈顶部。
int search(Object o)
返回对象在堆栈中的位置,以 1 为基数。
注意:
java.util.EmptyStackException
EmptyStackException: 空栈异常
产生原因: 栈里面的数据没有了
解决办法: 在弹栈之前做判断
示例代码如下:
Stack<String> stack = new Stack<>();
// 压栈
stack.push("abc");
stack.push("efg");
stack.push("hij");
while (!stack.isEmpty()) {
System.out.println("栈顶元素:" + stack.peek());
// 弹栈
System.out.println("弹出栈顶元素:" + stack.pop());
System.out.println(stack.search("hij432"));
// 返回对象在堆栈中的位置,以 1 为基数。
}