Java集合概述
在Java中,集合主要包括以下四种:
- Collection
- List
- Set
- Iterator
- Map
虽然List、Set是Collection的子接口,但是这里分开讲
Map、和Collection属于同一级别
Collection接口
- 动态对象数组,区别于数组的是可以对象的内容可以任意扩充
- 特点:性能高;容易扩展和修改
- Collection常用子类:List、Set、Queue
List接口
可以存放任意的数据
数据可以重复
List常用子类:ArrayList、Vector
常用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16boolean isEmpty(); // 判断集合是否为空
int indexOf(Object o); // 查找指定的对象是否存在(遍历方式查找)
// 将nums数组转换为list
List<Integer> list = Arrays.stream(nums).boxed().toList();
List<Integer> list = Arrays.stream(nums).boxed().collect(Collectors.toList());
// 在Java 16及更高版本中,Stream.toList()返回的是一个不可修改的列表
// 因此在尝试对其排序时会出现错误。可以改用Collectors.toList()来创建一个可修改的列表
// list转换为数组
list
.stream().sorted() // 排序,返回的是Stream<T>
.toList().toArray(numbers); // 转换为数组,需要先转换为List(stream也有toList方法,不转换为list,会报错)
// lambda写法
Integer[] numbers = list.stream().sorted().toArray(Integer[]::new); // 写法①:流直接转换为数组
Integer[] numbers = list.stream().sorted().toList().toArray(Integer[]::new); // 写法②:流先转换为list,再转换为数组比较Vector
比较 Array List Vector 推出时间 JDK1.2之后推出 JDK1.0 性能 采用异步处理方式,性能高 采用同步处理方式,性能低 线程安全 属于非线程安全 属于线程安全
Set接口
不能加入重复元素
可以排序(本身不支持排序,它是基于哈希表实现的,不保证元素的顺序。但是,可以将
HashSet
的元素转移到一个排序的列表或集合中,如TreeSet
,TreeSet
自动对元素进行排序(红黑树算法),因为它实现了SortedSet
接口。)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public static void main(String[] args) {
HashSet<Integer> hashSet = new HashSet<>();
hashSet.add(3);
hashSet.add(1);
hashSet.add(4);
hashSet.add(2);
hashSet.add(5);
// 将 HashSet 元素添加到 TreeSet 中,自动排序
TreeSet<Integer> treeSet = new TreeSet<>(hashSet);
// 打印排序后的元素
for (Integer number : treeSet) {
System.out.println(number);
}
}常用子类:HashSet、TreeSet
与list转换:
1
2set.stream().collect(Collectors.toList()); // 借助流,转换为List类型
new ArrayList<>(itemIds) // 效果等同
Iterator接口
集合输出的标准操作:标准操作,使用Iterator接口
操作原理:Iterator是专门的迭代输出接口,迭代输出就是将元素一个个进行判断,判断其是否有内容,如果有内容则把内容取出
常用方法:
1
2
3boolean hasNext(); // 如果仍有元素可以迭代,则返回true
E next(); // 返回迭代的下一个元素
void remove(); // 从迭代器指向的collection中移除迭代器返回的最后一个元素案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34public static void main() {
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
list.add("F");
Iterator<String> iter = list.iterator();
while(iter.hasNext()){
String str = iter.next();
if ("A".equals(str)) {
iter.remove();
} else {
System.out.println(str);
}
}
/**
* list set
*/
}
// 错误示范:集合迭代时,不能同时进行元素删除
while(iter.hasNext()){
String str = iter.next();
if ("A".equals(str)) {
iter.remove();
}
}
Map接口
- 保存形式:
- key ——> value的方式保存
- 例:小雪:15806880888
- 常用子类:
- HashMap:无序存放,key不允许重复
- Hashtable:无序存放,key不允许重复
- TreeMap:(按键)有序(红黑树算法)存放,key不允许重复
Stack接口
Stack继承了Vector,Vector和ArrayList类似,都是动态的顺序表
常用方法:
方法 功能 Stack() 构造一个空的栈 E push(E e) 将e入栈,并返回e E pop() 将栈顶元素出栈并返回 E peek() 获取栈顶元素 int size() 获取栈中有效元素个数 boolean empty() 检测栈是否为空
Queue接口
Queue是普通队列,Deque是双端队列
普通队列常用的类有:PriorityQueue优先权队列
双端队列常用类有:LinkedList队列、ArrayDeque队列
Java 已不推荐使用 Stack,而是推荐使用更高效的 ArrayDeque,次选 LinkedList 。
Queue和Deque常用方法对比:
操作 Queue方法 Deque方法 会抛异常 入队 add(e) addLast(e) 出队 remove() removeFirst() 得到队头的引用 element() getFirst() 不会抛异常 入队 offer(e) offerLast(e) 出队 poll() pollFirst() 得到队头的引用 peek() peekFirst() Deque作为双端队列的特有方法:
操作头 操作头 操作尾 操作尾 会抛异常 不会抛异常 会抛异常 不会抛异常 插入 addFirst(e) offerFirst(e) addLast(e) offerLast(e) 删除 removeFirst() pollFirst() removeLast() pollLast() 取值 getFirst() peekFirst() getLast() peekLast()