1.List
List是一个接口:父接口Collection ,它是Java集合框架(Java Collections Framework)的一部分。List接口表示一个有序集合(也称为序列),它允许存储元素(对象)的列表。列表中的每个元素都有一个位置索引,从0开始。列表允许有重复的元素。
1.1.ArrayList
基于动态数组实现的List,随机访问元素很快,但在列表中间插入或删除元素较慢。
ArrayList<Integer> arrayList=new ArrayList<>();
arrayList.add(12);
arrayList.add(6);
arrayList.add(3);
arrayList.add(11);
Collections.sort(arrayList);
System.out.println(arrayList);
System.out.println(arrayListcontains(2)); //是否包含2
1.2.LinkedList
基于链表实现的List,在列表中间插入或删除元素很快,但随机访问元素较慢。
LinkedList<String> linkedList=new LinkedList<>();
linkedList.add("abc");
linkedList.add("bca");
linkedList.add("cba");
linkedList.addFirst("va");
System.out.println(linkedList.peek());//不删除元素
2.Set
Set是Java集合框架中的一个重要接口,它表示一个不包含重复元素的集合。Set接口与List接口的主要区别在于Set不允许存储重复的元素,而List则允许。Set的实例不会保持元素的特定顺序(除非它是LinkedHashSet或TreeSet的实例,它们分别按照插入顺序或自然顺序维护元素的顺序)
2.1 HashSet
基于HashMap实现的Set,它提供了快速的查找、添加和删除操作。元素在HashSet中的顺序并不稳定,每次运行程序时,元素顺序可能都不同。HashSet允许null元素。
import java.util.HashSet;
public class HashSetExample {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Cherry");
System.out.println("HashSet contains Apple: " + set.contains("Apple")); // 输出: true
set.remove("Banana");
for (String fruit : set) {
System.out.println(fruit);
}
System.out.println("Size of HashSet: " + set.size()); // 输出: 2
}
}
2.2 LinkedHashSet
使用链表维护元素的插入顺序。在遍历LinkedHashSet时,元素的顺序将与它们被添加到集合中的顺序一致。性能略低于HashSet,因为维护了元素的插入顺序。
LinkedHashSet的主要特性在于它能够保持元素的插入顺序。这意味着,当你遍历一个LinkedHashSet时,元素会按照它们被添加到集合中的顺序出现。此外,由于LinkedHashSet在内部使用了链表来维护元素的插入顺序,因此其性能相对于HashSet会略低一些,但通常仍能满足大多数无序集合的需求。
2.3 TreeSet
TreeSet 的内部实现基于 NavigableMap(通常是一个 TreeMap),所以它的元素是排序的,要么根据元素的自然顺序,要么根据创建 TreeSet 时提供的 Comparator。
2.4 CopyOnWriteArraySet
基于“写时复制”的思想实现,即当修改操作(add、set等)对CopyOnWriteArraySet进行修改时,会先复制原数组,在新的数组上进行修改,然后再将新数组替换为原数组。这种机制使得CopyOnWriteArraySet具有很好的并发性能,特别适用于读多写少的并发场景。
特性:
线程安全:CopyOnWriteArraySet是线程安全的,可以在多线程环境下使用,每个线程对集合的操作都是独立的,不会相互影响。
无序:它是一个无序的集合,元素在集合中的顺序是不确定的。
写时复制:当对集合进行修改时,会先将原数组复制一份,然后在新数组上进行修改,最后将新数组替换为原数组。这种机制可以确保在修改过程中,其他线程读取到的数据仍然是一致的。
支持迭代器:CopyOnWriteArraySet支持迭代器操作,可以使用迭代器来遍历集合中的元素。
3.Queue
add(E e): 将指定元素插入此队列(如果立即可行且不会违反容量限制),成功时返回 true。
offer(E e): 将指定元素插入此队列(如果立即可行且不会违反容量限制),成功时返回 true,如果当前没有可用的空间,则返回 false。
remove(): 检索并删除此队列的头部。如果此队列为空,则抛出 NoSuchElementException。
poll(): 检索并删除此队列的头部,如果此队列为空,则返回 null。
element(): 检索但不删除此队列的头部。如果此队列为空,则抛出 NoSuchElementException。
peek(): 检索但不删除此队列的头部。如果此队列为空,则返回 null。
3.1 LinkedList:
Queue<Integer> q=new LinkedList<>();
q.add(2);
q.add(3);
q.add(4);
System.out.println(q.poll());
System.out.println(q.peek());
System.out.println(q.isEmpty());
3.2 ArrayDeque
一个基于数组的双端队列,它提供了在两端插入和移除元素的高性能操作。对于大多数队列应用来说,ArrayDeque是一个很好的选择,因为它提供了更好的性能。
Deque<Integer> dq=new ArrayDeque<>();
dq.addFirst(21);
dq.addLast(22);
PriorityQueue<Integer> pq=new PriorityQueue<>();
3.3 PriorityQueue
基于优先级堆的无界队列。元素根据其自然顺序或者创建PriorityQueue时提供的Comparator进行排序。这不是一个严格的FIFO队列,而是根据元素的优先级进行排序。
//小堆,将o1-o2改为o2-o1变成大堆
PriorityQueue<Integer> pqi=new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1-o2;
}
});
pqi.add(2);
pqi.add(1);
pqi.add(4);
pqi.add(3);
pqi.offer(0);
System.out.println(pqi.peek());
System.out.println(pqi.poll());