目录
一、认识集合
Java 中集合体系:
java 中的集合框架主要从三个方面入手:
二、Collection接口
Collection接口是Java标准库中的一个接口,用于表示一组对象的集合。
public interface Collection<E>
extends Iterable<E>
从类的声明我们可以看到, Collection 接口继承了 Iterable 接口。也就意味着,实现了Collection 接口的类也间接实现了 Iterable 接口,也就是说它们都能作为 for - each - loop 的循环对象。
Collection 是集合层次结构中的根接口。集合表示一组对象,对象称为集合的元素。有些集合允许重复元素,有些则不允许。 有些是有序的,有些是无序的(不保证顺序)
抽象方法:
add(E e) | boolean |
添加元素
|
addAll(Collection<?extends E>c) | boolean |
将集合 c 中的所有元素添加此集合中
|
clear() | void |
清除所有元素
|
contains(Object o) | boolean |
集合中是否包含此元素
|
containsAll(Collection<?>c) | boolean |
集合中是否包含 c 集合中的所有元素
|
iterator() | Iterator<E> |
继承自 Iterable 接口,返回集合的迭代器
|
retainAll(Collection<?>c) |
boolean
|
保留集合 c 中的元素
|
stream() | Stream<E> | 返回以此集合作为其源的Stream序列 |
toArray()
|
Object[]
|
返回一个包含此集合中所有元素的数组
|
子接口很多,主要研究 List 、 Set 、 Queue 。
Collection接口的实现类包括常见的ArrayList、LinkedList、HashSet、TreeSet、LinkedHashSet。
三、Iterable接口
java.lang.Iterable接口是Java标准库中的一个接口,用于表示可迭代的集合类。实现了Iterable接口的类可以使用Java中的for-each循环语句来遍历其元素,使其具有可迭代的特性。
void | foreach(Consumer<?super T>action) | 对Iterable对象的每个元素执行给定的操作,直到处理完所有元素或操作引发异常。 |
Iterator<T> | iterator() | 返回type T 元素的迭代器。 |
实现了Iterable接口的类可以通过实现iterator()方法来返回一个迭代器对象,使其可以使用for-each循环语法来遍历集合中的元素。例如,ArrayList、LinkedList、HashSet、TreeSet等集合类都实现了Iterable接口,因此可以直接用for-each循环来遍历他们的元素。
实现了Iterable接口的类应该保证其迭代器的行为是一致的,即多次调用iterator()方法返回的迭代器应该具有相同的遍历顺序和结果。同时,如果集合在迭代过程中发生了结构性变化(如添加、删除元素),应该抛出ConcurrentModificationException异常来通知迭代器和调用者。
四、Queue接口
4.1Queue接口概述
public interface Queue<E>
extends Collection<E>

特殊值(或者 null 或 false ,取决于操作)。
add(E element) | boolean |
如果可以在不违反容量限制的情况下立即将指定元素插入此队列,则在成功时返回 true . 当前没有可用空间抛出一个IllegalStateException
|
offer(E e)
|
boolean |
如果可以在不违反容量限制的情况下立即插入,则将指定元素插入此队列
|
element ()
|
E
|
检索但不删除此队列的头部 , 此方法的不同之处 peek 仅在于如果此队列为空,它会引发异常
|
peek()
|
E |
检索不删除此队列的头,如果此队列为空,则返回 null ,如果不为空返回队列的头
|
poll()
|
E |
检索并删除此队列的头,如果此队列为空,则返回 null
|
remove()
|
E |
检索并删除此队列的头。 此方法与 poll 不同之处在于,如果此队列为空,它将抛出异常。
|
Queue接口的实现类有很多,例如常用的LinkedList、ArrayDeque,Queue接口不允许插入null元素,也不允许包含重复的元素。
4.2 Deque接口
public interface Deque<E>
extends Queue<E>
继承了 Queue ,支持两端(首尾)元素插入和移除的线性集合。
java.util.Deque接口(双端队列)是Java标准库中的一种集合接口,代表了一种具有队列和栈特性的数据结构,支持在队列的两端进行插入和删除操作。Deque接口继承自Queue接口。
Deque接口的主要特点:
(1)双向操作:Deque接口允许在队列的两端进行插入、 删除、检索操作。
(2)队列特性:Deque接口支持队列的特性,支持FIFI(先进先出)的队列行为。
(3)栈特性:Deque接口支持栈的特性,支持LIFO(后进先出)的队列行为。
(4)实现类:包括ArrayDeque和LinkedList。
常用抽象方法:
addFirst(E e)
|
void
|
插入此双端队列的前面
|
addLast(E e)
|
void |
双端队列的末尾插入元素
|
getFirst()
|
E |
检索,但不删除,第一个元素
|
getLast()
|
E |
检索,但不删除,最后一个元素
|
pop()
|
E |
删除并返回此 deque 的第一个元素
|
push(E e)
|
E |
相当于 addFirst(E)
|
removeFirstOccurr
ence(Object o)
|
boolean
|
从此双端队列中删除第一次出现的指定元素。如果双端队列不包含该元素,则它保持不变
|
removeLastOccurre
nce(Object o)
|
boolean |
从此双端队列中删除最后一次出现的指定元素。如果双端队列不包含该元素,则它保持不变。
|
五、List接口
5.1 使用ArrayList类动态存储数据
ArrayList集合类对数组进行了封装,实现了长度可变的数组,而且和数组采取相同的存储方式,在内存中分配连续的空间,称ArrayList为动态数组。但不等同于数组,ArrayList集合中可以添加任何类型的数据,添加的数据都将转换成Object类型,在数组中只能添加同一类型的数据。
实现了List接口,底层使用数组保存所有的元素。每个ArrayList都有一个容量,该容量是指用来存储列表元素的数组的大小。
5.1.1 ArrayList定义类有两个私有属性
private transient Object[] elementData;
private int size;
transient关键字:Javaz中的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来为了在一个特定对象的一个域上关闭serialization,就在这个与前加上关键字transient。
5.1.2 构造方法
ArrayList提供三种方式的构造器,可以构造一个默认初始容量为10的空列表、构造一个指定初始容量的空列表以及构造一个指定collection的元素的列表。
private static final int DEFAULT_CAPACITY=10;
private static final Object[] EMPTY_ELEMENTDATA={};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA={};
public ArrayList(int initialCapacity){
if (initialCapacity>0){
this.elementData=new Object()[initialCapacity];
}else if (initialCapacity==0){
this.elementData=EMPTY_ELEMENTDATA;
}else {
throw new IllegalStateException("Illegal Capacity:"+initialCapacity);
}
}
public ArrayList(){
this.elementData=DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public ArrayList(Collection<? extends E> c){
Object[] a=c.toArray();
if ((size==a.length)!=0){
if (c.getClass()==ArrayList.class){
elementData=a;
}else {
elementData= Arrays.copyOf(a,size,Object[].class);
}
}else {
elementData=EMPTY_ELEMENTDATA;
}
}
5.1.3 操作数据
add(int index, E element)
|
void
|
将指定的元素插入此列表中的指定位置
|
add(E e) | boolean | 将指定的元素添加到此列表的末尾 |
addAll(int index,Collection<? extends E> c)
|
boolean |
将指定集合中的所有元素插入到此列表中的指定位置
|
addAll(Collection<? extends E> c) | boolean | 将指定集合中的所有元素追加到此列表的末尾,按照他们由指定集合的迭代器返回的顺序 |
removeRange(int fromIndex,int toIndex) | protected void | 从此列表中删除索引介于fromIndex和toIndex之间的所有元素 |
trimToSize() | void | 将此实例的容量修剪为列表的大小 |
default sort(Comparator c)
|
void
|
按照 c 比较器进行自然排序 JDK 8
|
static copyOf(Collection coll)
|
List
|
按照迭代顺序返回一个不可修改的 List . JDK 10
|
static of()
|
List |
返回包含任意数量元素的不可修改列表 JDK9
|
5.2 使用LinkedList类动态存储数据
能将LinkedList当作双端队列使用,优点在于插入、删除元素时效率比较高,但是LinkedList类的查找效率低。
5.2.1 LinkedList中定义的属性
transient int size=0;
transient LinkedList.Node<E> first;
transient LinkedList.Node<E> last;
(1)size:双向列表的节点个数
(2)first:双向链表指向头节点的指针
(3)last:双向链表指向尾节点的指针
5.2.2 Node类定义
private static class Node<E>{
E item;
LinkedList.Node<E> next;
LinkedList.Node<E> prev;
Node(E element, LinkedList.Node<E> next, LinkedList.Node<E> prev) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
5.2.3 构造方法
public LinkedList(){
}
public LinkedList(Collection<? extends E> c){
this();
addAll(c);
}
5.2.4 操作数据
offer(E e) | boolean | 添加指定元素作为此列表的尾部 |
5.3 Vector

addElement(E obj) | void | 将指定的组件添加到末尾,将其大小增加1 |
copyInto(Object[] anArray) | void | 复制到指定的数组中 |
elementAt(int index) | E | 返回指定索引处的组件 |
5.4 Stack
public class Stack<E> extends Vector<E>
search(Object o)
|
int
|
返回对象在此堆栈上的从 1 开始的位置
|
package collection;
import java.util.Stack;
public class ArrayListExample {
public static void main(String[] args) {
//创建一个Stack对象
Stack<Integer> stack=new Stack();
//添加元素
stack.push(1);
stack.push(2);
stack.push(3);
//弹出并删除元素
int pop = stack.pop();
System.out.println(pop);
System.out.println(stack);
//弹出但是不删除
Integer peek = stack.peek();
System.out.println(peek);//2
//判断是否为空
boolean empty = stack.isEmpty();
System.out.println(empty);//false
//获取元素个数
System.out.println(stack.size());//2
//搜索元素在栈中的位置
int search = stack.search(1);
System.out.println(search);
}
}