继续昨天讲的第四道练习:
- 反转单链表
用递归的方式
/*
反转单链表
*/
public class Ex1 {
public static Node reverse(Node head) {
// 边界条件
if(head == null || head.next == null) return head;
// 反转head.next
Node reversed = reverse(head.next);
// 反转头结点
head.next.next = head;
head.next = null;
return reversed;
}
// 1 --> 2 --> 3
public static void print(Node head) {
Node x = head;
while (x.next != null) {
System.out.print(x.value + " --> ");
x = x.next;
}
System.out.println(x.value);
}
public static void main(String[] args) {
// 1 --> 2 --> 3
Node head = new Node(3);
head = new Node(2, head);
head = new Node(1, head);
Node reversed = reverse(head);
print(reversed);
}
}
List的子类
ArrayList
概述:
- 底层数据结构是数组,增删慢,查找快。
- 不同步, 线程不安全, 效率高。
- 允许存储null元素
- 不需要担心它的容量,因为可以自动扩容,但会耗费性能
构造方法:
- ArrayList() 默认初始大小为10
- ArrayList(int initialCapacity) 可以指定数组的初始大小
- ArrayList(Collection c) 将集合c中的元素复制一份到ArrayList中
public class ArrayListDemo1 {
public static void main(String[] args) {
// ArrayList()
/*ArrayList list = new ArrayList();
for (int i = 0; i < 20; i++) {
list.add(i);
}
System.out.println(list);
System.out.println(list.size());*/
// ArrayList(int initialCapacity)
/*ArrayList list = new ArrayList(20);
for (int i = 0; i < 20; i++) {
list.add(i);
}
System.out.println(list);
System.out.println(list.size());*/
// ArrayList(Collection c)
Collection c = new ArrayList();
c.add("hello");
c.add("world");
c.add(null);
ArrayList list = new ArrayList(c);
System.out.println(list);
System.out.println(list.size());
list.set(1, "WORLD");
System.out.println(list);
System.out.println(c);
}
}
API:
提供操作内部数组大小的方法
void ensureCapacity(int minCapacity)
// 避免频繁扩容
如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。
应用场景:刚开始我们不知道存储多少元素,用ArrayList():的构造方法去初始化了一个ArrayList,但到了某个时候,知道应该存多少元素了,就用这种方法。
void trimToSize()
// 将数组缩小到size大小
注意事项:当你确定元素大小不再添加的时候,我们可以使用trimToSize()
Vector
概述:
- 底层是数组,查找快,增删慢
- 同步, 线程安全, 效率低
- 存储null元素
API:
void addElement(E obj) --> void add(E e)
void copyInto(Object[] anArray) --> Object[] toArray()
E elementAt(int index) --> E get(int index)
void insertElementAt(E obj, int index) --> void add(int index, E e)
void removeAllElements() --> void clear()
boolean removeElement(Object obj) --> boolean remove(Object obj)
void removeElementAt(int index) --> E remove(int index)
void setElementAt(E obj, int index) --> E set(int index)
Enumeration<E> elements() --> Iterator iterator()
int capacity() // 返回此向量的当前容量。默认也是10
void setSize(int newSize) // 设置此向量的大小。
capacity和size不一样,capacity是Vector占用的总空间的大小,而size是Vector中真正存储元素的总空间的大小
E firstElement()
E lastElement()
//返回第一个和最后一个元素,如果Vector为空,报错:NoSuchElementException
int indexOf(Object o, int index)
//从index开始向后查找元素o,返回查到的第一个o的索引下标
int lastIndexOf(Object o, int index)
//从index开始向前查找元素o,返回查到的第一个o的索引下标
看一下Enumeration elements()这个方法:
Enumeration接口 --> Iterator
API:
boolean hasMoreElements() --> boolean hasNext()
E nextElement() --> E next()
LinkedList
概述:
- 底层数据结构是链表,查询慢,增删快
- 不同步, 线程不安全,效率高
- 允许null元素
- 实现了Deque接口
Collection
- |-- Queue
- |-- Deque (double ended queue)
Deque
概述:
只能在线性表的两端操作(添加, 删除, 查找), 可以被用作栈、队列、双端队列
栈:
- void push(E e)
- E pop()
- E peek()
队列:
- void add(E e) E remove() E element()
- void offer(E e) E poll() E peek()
双端队列:
- void addFirst(E e) E removeFirst() E getFirst()
- void addLast(E e) E removeLast() E getLast()
- void offerFirst(E e)E pollFirst() E peekFirst()
- void offerLast(E e) E pollLast() E peekLast()