Java SE中的集合框架是一组用于存储和操作对象的类和接口。它提供了丰富的数据结构,可以用于解决各种问题。Java SE中的集合框架包含以下主要类和接口:
一. Collection接口:
是集合框架的根接口,它定义了一些通用的集合操作方法,比如添加、删除、查找、遍历等。
作为集合框架的根接口,Collection接口定义了一些通用的集合操作方法,下面举例说明这些方法的用法:
1.添加元素:使用add()方法将指定的元素添加到集合中。
Collection<String> collection = new ArrayList<>();
collection.add("apple");
collection.add("banana");
- 删除元素:使用remove()方法从集合中删除指定的元素。
collection.remove("apple");
- 查找元素:使用contains()方法判断集合中是否包含指定的元素。
boolean containsApple = collection.contains("apple");
- 遍历集合:使用迭代器(iterator()方法)或者增强for循环(foreach)来遍历集合中的元素。
Iterator<String> iterator = collection.iterator();
while(iterator.hasNext()){
String element = iterator.next();
System.out.println(element);
}
for(String element : collection){
System.out.println(element);
}
- 获取集合大小:使用size()方法获取集合中的元素个数。
int size = collection.size();
- 判断集合是否为空:使用isEmpty()方法判断集合是否为空。
boolean isEmpty = collection.isEmpty();
- 清空集合:使用clear()方法清空集合中的所有元素。
collection.clear();
需要注意的是,Collection接口中的方法都是抽象方法,具体的实现在其子类中完成。
二. List接口:
List接口是Collection接口的子接口,表示一个有序集合,可以包含重复元素。List接口的常见实现类有:
ArrayList:基于动态数组实现,支持随机访问,插入和删除元素的效率较低。
LinkedList:基于双向链表实现,支持快速插入和删除元素,但访问元素的效率较低。
Vector:基于动态数组实现,与ArrayList类似,但线程安全,不推荐使用。
Stack:基于Vector实现,表示一个后进先出(LIFO)的堆栈结构。
CopyOnWriteArrayList:基于数组实现,可以在迭代的同时进行插入和删除操作,适用于读多写少的场景。
除了这些常见的实现类之外,还可以通过继承AbstractList类或实现List接口来创建自定义的List实现类。下面举例说明List接口的用法:
- 创建List集合并添加元素:
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("apple"); //可以添加重复元素
- 获取元素:
String firstElement = list.get(0); //获取索引为0的元素
- 修改元素:
list.set(0, "orange"); //将索引为0的元素修改为"orange"
- 删除元素:
list.remove("apple"); //删除指定元素
list.remove(0); //删除索引为0的元素
- 查找元素:
boolean containsApple = list.contains("apple"); //判断集合中是否包含"apple"
int index = list.indexOf("banana"); //查找元素"banana"的索引
- 获取集合大小:
int size = list.size(); //获取集合的大小
- 遍历集合:
for(String element : list){
System.out.println(element);
}
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
String element = iterator.next();
System.out.println(element);
}
需要注意的是,List接口是有序的,可以通过索引访问元素。同时,List接口中也继承了Collection接口中的方法,可以使用Collection接口中的通用方法对List进行操作。
三. Set接口:
Set接口是Collection接口的子接口,表示一个无序、不重复的集合。Set接口的常见实现类有:
- HashSet:基于哈希表实现,不保证元素的顺序,可以存储null元素。
- TreeSet:基于红黑树实现,保证元素的有序性,不允许存储null元素。
- LinkedHashSet:基于哈希表和链表实现,保证元素的插入顺序,允许存储null元素。
- EnumSet:专门用于存储枚举类型的集合。
- CopyOnWriteArraySet:基于数组实现,可以在迭代的同时进行插入和删除操作,适用于读多写少的场景。
除了这些常见的实现类之外,还可以通过继承AbstractSet类或实现Set接口来创建自定义的Set实现类。下面举例说明Set接口的用法:
- 创建Set集合并添加元素:
Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
set.add("apple"); //不会添加重复元素
- 查找元素:
boolean containsApple = set.contains("apple"); //判断集合中是否包含"apple"
- 删除元素:
set.remove("apple"); //删除指定元素
- 获取集合大小:
int size = set.size(); //获取集合的大小
- 遍历集合:
for(String element : set){
System.out.println(element);
}
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()){
String element = iterator.next();
System.out.println(element);
}
需要注意的是,Set接口是无序的,不保证元素的存储顺序。同时,Set接口中也继承了Collection接口中的方法,可以使用Collection接口中的通用方法对Set进行操作。另外,TreeSet是Set接口的有序实现类,它会按照元素的自然顺序进行排序。
四. Map接口:
Map接口是用于存储键值对的集合,它是集合框架中的一部分。Map接口的常见实现类有:
- HashMap:基于哈希表实现,不保证键值对的顺序,可以存储null键和null值。
- TreeMap:基于红黑树实现,保证键值对的有序性,不允许存储null键,但可以存储null值。
- LinkedHashMap:基于哈希表和链表实现,保证键值对的插入顺序,允许存储null键和null值。
- Hashtable:基于哈希表实现,保证键值对的同步访问,不保证键值对的顺序,不允许存储null键和null值。
- ConcurrentHashMap:基于哈希表和分段锁实现,并发安全的Map,允许并发地进行读写操作。
- EnumMap:专门用于存储枚举类型作为键的集合。
除了这些常见的实现类之外,还可以通过继承AbstractMap类或实现Map接口来创建自定义的Map实现类。下面举例说明Map接口的用法:
- 创建Map并添加键值对:
Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
map.put("orange", 3);
- 获取键对应的值:
int appleValue = map.get("apple"); //获取键"apple"对应的值
- 判断是否包含键:
boolean containsKey = map.containsKey("apple"); //判断是否包含键"apple"
- 判断是否包含值:
boolean containsValue = map.containsValue(1); //判断是否包含值1
- 删除键值对:
map.remove("apple"); //删除键"apple"对应的键值对
- 遍历键值对:
for(Map.Entry<String, Integer> entry : map.entrySet()){
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key + " : " + value);
}
Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry<String, Integer> entry = iterator.next();
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key + " : " + value);
}
需要注意的是,Map接口中的键是唯一的,不允许重复,如果重复添加相同的键,后面的值会覆盖前面的值。另外,LinkedHashMap是Map接口的有序实现类,它会根据元素的插入顺序进行排序。
五. Queue接口:
Queue接口是集合框架中用于表示队列的接口,它继承自Collection接口。Queue接口支持元素的插入和移除操作,Queue接口的常见实现类有:
-
LinkedList:基于双向链表实现的队列,可以作为Queue接口的实现类。
-
ArrayDeque:基于数组实现的双端队列,也可以作为Queue接口的实现类。
-
PriorityQueue:基于优先级堆实现的队列,可以根据元素的优先级进行插入和删除操作。注意,它不是严格意义上的队列,因为删除元素时不一定按照插入的顺序进行。
-
ConcurrentLinkedQueue:线程安全的非阻塞队列,基于链表实现,支持多线程并发操作。
除了这些常见的实现类之外,还可以通过继承AbstractQueue类或实现Queue接口来创建自定义的Queue实现类。下面举例说明Queue接口的用法: -
创建Queue并添加元素:
Queue<Integer> queue = new LinkedList<>();
queue.offer(1); //插入元素1
queue.offer(2); //插入元素2
queue.offer(3); //插入元素3
- 获取并移除队列的头部元素:
int head = queue.poll(); //获取并移除队列的头部元素,此时head的值为1
- 获取但不移除队列的头部元素:
int head = queue.peek(); //获取但不移除队列的头部元素,此时head的值为2
- 判断队列是否为空:
boolean isEmpty = queue.isEmpty(); //判断队列是否为空,此时isEmpty的值为false
- 获取队列的大小:
int size = queue.size(); //获取队列的大小,此时size的值为2
需要注意的是,LinkedList实现了Deque接口,因此可以被当作双端队列使用。PriorityQueue是一个基于优先级堆的无界优先级队列,它根据元素的自然顺序或者指定的Comparator进行排序。
六. Stack类:
Stack类是Java中表示后进先出(LIFO)的堆栈的类,它继承自Vector类,实现了栈的基本操作。下面举例说明Stack类的用法:
- 创建Stack对象并添加元素:
Stack<Integer> stack = new Stack<>();
stack.push(1); //将元素1推入栈顶
stack.push(2); //将元素2推入栈顶
stack.push(3); //将元素3推入栈顶
- 获取并移除栈顶元素:
int top = stack.pop(); //获取并移除栈顶元素,此时top的值为3
- 获取但不移除栈顶元素:
int top = stack.peek(); //获取但不移除栈顶元素,此时top的值为2
- 判断栈是否为空:
boolean isEmpty = stack.isEmpty(); //判断栈是否为空,此时isEmpty的值为false
- 获取栈的大小:
int size = stack.size(); //获取栈的大小,此时size的值为2
需要注意的是,Stack类是线程安全的,但因为它继承自Vector类,所以性能上可能不如使用LinkedList实现的双端队列。因此,如果只需要使用栈的功能,推荐使用Deque接口的实现类LinkedList来代替Stack类。
七. Iterator接口:
用于迭代访问集合中的元素。
Iterator接口是Java中用于迭代访问集合中元素的接口,通过它可以依次访问集合中的每个元素。下面举例说明Iterator接口的用法:
- 创建Iterator对象并遍历集合:
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("orange");
Iterator<String> iterator = list.iterator(); //获取Iterator对象
while (iterator.hasNext()) { //判断是否还有下一个元素
String element = iterator.next(); //获取下一个元素
System.out.println(element);
}
输出结果:
apple
banana
orange
- 在遍历过程中删除元素:
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("orange");
Iterator<String> iterator = list.iterator(); //获取Iterator对象
while (iterator.hasNext()) {
String element = iterator.next();
if (element.equals("banana")) {
iterator.remove(); //删除当前元素
}
}
System.out.println(list);
输出结果:
[apple, orange]
需要注意的是,Iterator接口的迭代器是单向的,只能从前往后遍历,而且在遍历过程中不能修改集合的结构(除了使用Iterator的remove方法)。
Java SE中的集合框架提供了丰富的方法和工具类,可以方便地对集合进行操作和处理。它提供了高性能的数据结构,可以应对不同的应用场景和需求。