集合框架
Java 集合框架提供了一套性能优良、使用方便的接口和类,他们都位于 java.util
包中。Java 集合框架由3大类接口构成(Map接口
、List接口
、Set接口
).
1. letrable 接口
java.lang.lterable
接口是 Java 标准库中的一个接口,用于表示可迭代的集合类。实现了 lterable
接口的类可以使用 Java 中的 for-each
循环来遍历其元素,使其具有可迭代的特性。
返回值类型 | 方法名 | 描述 |
---|---|---|
Iterator<E> |
iterator() |
返回一个迭代器,用于遍历集合中的元素。 |
void |
forEach(Consumer<? super E> action) |
对集合中的每个元素执行给定操作。 |
Spliterator<E> |
spliterator() |
返回一个拆分器,用于对集合中的元素进行分割迭代。 |
例子
java
import java.util.*;
public class VectorExample {
public static void main(String[] args) {
Vector<Student> students = new Vector<Student>();
students.add(new Student("犯困桃子", 10, 11));
students.add(new Student("小羊呆呆", 20, 11));
students.add(new Student("中科盛康人才", 5, 11));
students.add(new Student("小羊", 30, 11));
students.add(new Student("盛康人才", 1, 11));
// 比较排序
Collections.sort(students, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
return Integer.compare(s1.getMath(), s2.getMath());
}
});
// 使用 for-each迭代输出
for (Student student : students) {
System.out.println(student);
}
students.get(3).setName("三娃"); // 设置名称
students.insertElementAt(new Student("五娃", 20, 17), 4); // 指定下标插入
System.out.println(students.size());
students.remove(students.size() - 1); // 删除最后一个元素
// 使用 iterator() 输出
Iterator<Student> iterator = students.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
2. Collection 接口
Collection
接口是 Java.util
包下的一个接口,用于表示一组对象是集合。它是 Java 集合框架中的根接口,继承了 lterable
接口,因此它可以用于遍历集合中的元素。Collection
接口提供了一组通用的方法,用于对集合进行基本的操作。
方法名 | 返回值 | 描述 |
---|---|---|
add(E e) | boolean | 添加元素 |
addAll(Collection<? extends E> c) | boolean | 将集合c中的所有元素添加到此集合中 |
clear() | void | 清除所有元素 |
contains(Object o) | boolean | 集合中是否包含指定元素 |
containsAll(Collection<?> c) | boolean | 集合是否包含指定集合中的所有元素 |
isEmpty() | boolean | 集合是否为空 |
iterator() | Iterator | 返回集合的迭代器 |
remove(Object o) | boolean | 删除集合中的某个元素 |
removeAll(Collection<?> c) | boolean | 删除集合中与指定集合中相同的所有元素 |
retainAll(Collection<?> c) | boolean | 保留集合中与指定集合中相同的元素 |
size() | int | 返回集合中的元素数 |
toArray() | Object[] | 返回包含集合中所有元素的数组 |
Collection
接口实现的类包括常见的 ArrayList
、LinkedList
、HashSet
、TreeSet
、LinkedHashSet
等。
2.1 队列(Queue)
java
public interface Queue<E>
extends Collection<E>
设计用于在处理之前保留元素的集合。 除了基本的 Collection
操作之外,队列还提供额外的插入,提取和检查操作,不可以存 null 。
下面是常用的Queue接口方法及其描述:
方法名 | 返回值类型 | 描述 |
---|---|---|
add(E e) | boolean | 将指定元素插入此队列 。如果队列已满,则会抛出IllegalStateException 异常 |
offer(E e) | boolean | 将指定元素插入此队列 。 如果队列已满,则会返回false |
remove() | E | 检索并删除此队列的头部 。如果队列为空,则会抛出NoSuchElementException 异常 |
poll() | E | 检索并删除此队列的头部,如果此队列为空,则返回null |
element() | E | 检索但不删除此队列的头部 。如果队列为空,则会抛出NoSuchElementException 异常 |
peek() | E | 检索但不删除此队列的头部,如果此队列为空,则返回null |
size() | int | 返回队列中的元素数 |
contains(Object o) | boolean | 如果此队列包含指定元素,则返回true |
clear() | void | 移除此队列中的所有元素 |
toArray() | Object[] | 返回包含此队列所有元素的数组;返回数组按照队列元素排列顺序 |
上述方法是 Queue
接口中常用的方法,通过实现该接口,并重写其中的方法,即可定义自己的队列实现类。Queue
接口实现的类有很多,例如常用的有 LinkedList
、ArrayDeque
等。
Queue 接口不允许插入 null 元素,也不允许包含重复的元素。
2.2 Deque(双端队列)
java
public interface Deque<E>
extends Queue<E>
继承了 Queue
,支持两端(首尾)元素插入和移除的线性集合。
方法名 | 返回值类型 | 描述 |
---|---|---|
addFirst(E e) | void | 在双端队列的前面插入元素 |
addLast(E e) | void | 在双端队列的末尾插入元素,类似于add(E e) |
getFirst() | E | 检索但不删除双端队列的第一个元素 |
getLast() | E | 检索但不删除双端队列的最后一个元素 |
pop() | E | 删除并返回双端队列的第一个元素 |
push(E e) | void | 相当于addFirst(E e),在双端队列的前面插入元素 |
removeFirstOccurrence(Object o) | boolean | 从双端队列中删除第一次出现的指定元素,如果不存在则保持不变 |
removeLastOccurrence(Object o) | boolean | 从双端队列中删除最后一次出现的指定元素,如果不存在则保持不变 |
2.3 set(集合)
java
public interface Set<E>
extends Collection<E>
集合中的对象并不能保存重复的对象,也就是说 Set
接口可以储存一组唯一、无序的对象。
在Java中,Set
是一种集合接口,它继承自Collection
接口。Set集合的主要属性如下:
-
无序性:
Set集合中的元素是无序排列的,不会按照插入顺序或者其他特定顺序进行存储。这是因为Set集合通常基于哈希表或红黑树实现,以提供快速的插入、删除和搜索操作。 -
唯一性:
Set集合中不允许包含重复的元素。当添加重复元素时,Set集合会自动拒绝并保留唯一性。 -
不允许使用索引:
Set集合没有提供索引访问元素的方法,因为它的元素是无序的。如果需要按索引访问元素,应该使用List集合。 -
添加、删除和包含操作的性能较高:
由于Set集合通常使用哈希表或红黑树实现,可以在常数时间内执行添加、删除和包含操作。 -
允许使用null元素:
Set集合允许存储一个null元素。但需要注意,HashSet和LinkedHashSet不保证存储顺序,而TreeSet不允许存储null元素。
常见的Set集合实现类有:
HashSet
:基于哈希表实现,具有较好的查找性能,不保证元素的存储顺序。LinkedHashSet
:基于哈希表和链表实现,按插入顺序保留元素,具有较好的遍历性能。TreeSet
:基于红黑树实现,按照元素的自然顺序或者指定的Comparator进行排序。
of
方法和copyOf
,都是static
方法返回一个不可修改的Set
集合。
2.4 list接口(列表)
有序集合(也称为序列 )。 该集合用户可以精确控制列表中每个元素的插入位置。 用户可以通过整数索引(列表中的位置)访问元素,并搜索列表中的元素。
List
通常允许重复的元素、允许null
元素
方法名 | 返回值类型 | 描述 |
---|---|---|
add(int index, E element) | void | 将指定的元素插入此列表中的指定位置 |
addAll(int index, Collection<? extends E> c) | boolean | 将指定集合中的所有元素插入到此列表中的指定位置 |
get(int index) | E | 返回此列表中指定位置的元素 |
indexOf(Object o) | int | 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回 -1 |
lastIndexOf(Object o) | int | 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回 -1 |
remove(int index) | E | 删除该列表中指定位置的元素,返回被删除的元素 |
set(int index, E element) | E | 用指定的元素(可选操作)替换此列表中指定位置的元素,返回被替换的值 |
subList(int fromIndex, int toIndex) | List | 返回此列表中指定的 fromIndex (含)和 toIndex之间的元素集合 |
default sort(Comparator c) | void | 按照 c 比较器进行自然排序 (JDK 8) |
static copyOf(Collection coll) | List | 按照迭代顺序返回一个不可修改的 List (JDK 10) |
static of() | List | 返回包含任意数量元素的不可修改列表 (JDK 9) |
示例
java
import java.util.List;
import java.util.Scanner;
public class ListExample01 {
public static void main(String[] args) {
// List不可修改
List commodity = List.of("棉花糖", "气球", "风筝", "饼干", "巧克力");
Scanner input = new Scanner(System.in);
System.out.println("请输入你要查询的商品信息");
String str = input.next();
if (commodity.contains(str)) {
String information = (String) commodity.get(commodity.indexOf(str));
System.out.println(information);
} else {
System.out.println("暂时没有这个商品");
}
}
}
主要子类: ArrayList
、 LinkedList
、 Vector
、Stack
等。
2.4.1 Vector 类动态储存数据
Vector
类是一种动态数组,它可以自动扩展和缩小数组的大小,实现了 List
接口,且所有的方法都是同步的(线程安全的),适用于多线程环境中的操作。
Vector
类的特点:
动态数组
:Vector的大小可以根据需要自动增长或减小。当添加元素超过当前容量时,Vector会自动重新分配内部数组的大小以容纳更多的元素。默认大小为10
,扩容为*2
。线程安全
:Vector是线程安全的,意味着多个线程可以同时对Vector进行读取和写入操作,而不会导致数据不一致的问题。Vector中的方法都使用了同步关键字来确保线程安全性。支持随机访问
:Vector类支持通过索引值来访问集合在的元素,具有常数时间度的随机访问特性。可以包含重复元素
可以插入 null
java
import java.util.Comparator;
import java.util.Iterator;
import java.util.Vector;
public class VectorExample02 {
public static void main(String[] args) {
Vector<Student> students = new Vector<Student>();
students.add(new Student("犯困桃子", 10, 91));
students.add(new Student("小羊呆呆", 20, 72));
students.add(new Student("中科盛康人才", 5, 35));
students.add(new Student("小羊", 30, 50));
students.add(new Student("盛康人才", 1, 11));
students.add(new Student("张三", 23, 90));
students.add(new Student("李四", 24, 80));
students.add(new Student("王五", 43, 70));
students.add(new Student("赵六", 24, 80));
students.add(new Student("田七", 25, 50));
students.sort(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return (sum(o1) - sum(o2)) * -1 ;
}
});
// Iterator<Student> iterator = students.iterator();
// while (iterator.hasNext()) {
// Student student = iterator.next();
// System.out.println(student + "\t" + avg(student));
// }
for (Student student : students) {
System.out.println("" + student + "\t 平均成绩:" + avg(student));
}
}
// 计算总成绩
public static int sum(Student student) {
return student.getTotal();
}
// 计算平均分
public static double avg(Student student) {
return (student.getTotal() / 2.0);
}
}
2.4.2 Stack 类动态存储数据
Stack
类代表后进先出(LIFO)
堆栈的对象, Stack
继承自 Vector
所以它有所有 Vector
中的方法。
java
public class Stack<E> extends Vector<E>
Stack 常用方法:
方法名 | 返回值类型 | 描述 |
---|---|---|
empty() | boolean | 判断此堆栈是否为空 |
peek() | E | 返回此堆栈顶部的对象,而不从堆栈中删除它 |
pop() | E | 返回并删除此堆栈顶部的对象 |
push(E item) | E | 将指定对象添加到堆栈的顶部 |
search(Object o) | int | 返回对象在此堆栈上的从1开始的位置,如果对象不在堆栈中,则返回 -1 |
示例
java
import java.util.Stack;
public class StackExample {
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
// 向Stack添加元素
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
// Stack 弹出元素
System.out.println(stack.pop()); // 4
// Stack 查看但不弹出
System.out.println(stack.peek()); // 3
// 判断是否为空
System.out.println(stack.isEmpty()); // false
// 查找元素所在位置
System.out.println(3); // 3
System.out.println(stack); // [1, 2, 3]
}
}