Java集合(Java Collections)是Java中用于存储、操作和管理一组对象的数据结构框架。它提供了一套接口和类,帮助开发者以统一的方式处理各种类型的集合,如列表、集合、队列和映射。Java集合框架使得开发者可以轻松地处理数据结构,不需要自己实现复杂的数据结构算法。
核心接口:
List
、Set
和Queue
接口都继承自Collection
。
ArrayList
、LinkedList
。HashSet
、TreeSet
。PriorityQueue
。ArrayDeque
。Map接口:
Collection
,但也是Java集合框架的一部分。它存储键值对,每个键都唯一。例如:HashMap
、TreeMap
、LinkedHashMap
。重要实现类:
List
实现,查找元素速度快,增删效率相对较慢。List
实现,增删速度快,查找效率较低。Set
,不保证元素顺序。Set
,元素是有序的。Map
,允许null
键和null
值。Map
,键按自然顺序或自定义比较器排序。Collections工具类:
Java集合框架通过使用泛型,提供了类型安全的集合操作,从而避免了在运行时发生类型转换错误。
你可以根据需要选择不同的集合类型来存储和操作数据。
Java中的Collections
工具类是一个包含多个静态方法的实用类,提供了对集合进行各种操作的工具。通过Collections
类,你可以执行排序、查找、同步化、打乱顺序等操作。以下是Collections
工具类的一些常用方法:
sort(List list)
:对List
集合中的元素进行升序排序,要求集合中的元素实现Comparable
接口。sort(List list, Comparator super T> c)
:使用指定的Comparator
对List
集合中的元素进行排序。reverse(List> list)
:将List
中的元素顺序反转。binarySearch(List extends Comparable super T>> list, T key)
:使用二分查找算法在有序List
中查找元素,返回元素的索引。binarySearch(List extends T> list, T key, Comparator super T> c)
:使用二分查找算法和自定义比较器查找元素。max(Collection extends T> coll)
:返回集合中的最大元素,要求集合中的元素实现Comparable
接口。max(Collection extends T> coll, Comparator super T> comp)
:使用指定的Comparator
,返回集合中的最大元素。min(Collection extends T> coll)
:返回集合中的最小元素。min(Collection extends T> coll, Comparator super T> comp)
:使用指定的Comparator
,返回集合中的最小元素。replaceAll(List list, T oldVal, T newVal)
:将List
中的所有oldVal
替换为newVal
。synchronizedList(List list)
:返回一个线程安全的List
。synchronizedSet(Set s)
:返回一个线程安全的Set
。synchronizedMap(Map m)
:返回一个线程安全的Map
。unmodifiableList(List extends T> list)
:返回一个不可修改的List
。unmodifiableSet(Set extends T> set)
:返回一个不可修改的Set
。unmodifiableMap(Map extends K, ? extends V> m)
:返回一个不可修改的Map
。shuffle(List> list)
:随机打乱List
集合中的元素顺序。shuffle(List> list, Random rnd)
:使用指定的随机数生成器打乱List
中的元素顺序。frequency(Collection> c, Object o)
:返回指定元素在集合中出现的次数。fill(List super T> list, T obj)
:将List
中的所有元素都替换为指定的元素。copy(List super T> dest, List extends T> src)
:将src
中的所有元素复制到dest
中,要求dest
至少与src
的大小相等。disjoint(Collection> c1, Collection> c2)
:如果两个集合没有交集,则返回true
。nCopies(int n, T o)
:返回包含n
个o
元素的不可修改列表。rotate(List> list, int distance)
:将List
中的元素按照指定距离旋转(正值右移,负值左移)。swap(List> list, int i, int j)
:交换List
中索引i
和索引j
处的元素。addAll(Collection super T> c, T... elements)
:向集合中添加多个元素。singleton(T o)
:返回一个只包含单一对象的不可修改Set
。singletonList(T o)
:返回一个只包含单一对象的不可修改List
。singletonMap(K key, V value)
:返回一个只包含单一键值对的不可修改Map
。emptyList()
:返回一个空的不可修改List
。emptySet()
:返回一个空的不可修改Set
。emptyMap()
:返回一个空的不可修改Map
。这些方法为开发者提供了丰富的集合操作手段,能够简化集合的处理工作,同时确保代码的简洁性和可读性。
在 Java 集合框架中,实现线程安全的集合类有多种方式。下面是几种常见的线程安全实现:
Vector
和 Hashtable
Vector
和 Hashtable
本身是线程安全的,因为它们的方法都使用了 synchronized
关键字。Collections.synchronizedXXX()
方法通过 Collections.synchronizedXXX()
方法,可以将非线程安全的集合(如 ArrayList
、HashMap
等)转换为线程安全的版本。
例如:
List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
Map<String, String> synchronizedMap = Collections.synchronizedMap(new HashMap<>());
这种方法会对整个集合的访问加锁,但需要注意的是,遍历集合时仍然需要手动同步:
synchronized(synchronizedList) {
for (String item : synchronizedList) {
// Do something with item
}
}
这种实现方法的优点是可以让你灵活地使用各种集合类,但由于它对每个方法调用加锁,性能可能较低。
ConcurrentHashMap
ConcurrentHashMap
是 HashMap
的线程安全版本,它使用了一种更高效的并发控制机制,允许多线程在不同的分段(segment)上并发读写,而不需要锁整个集合。
相比 Collections.synchronizedMap
,ConcurrentHashMap
在并发性能上有显著提升,尤其是读多写少的场景。
例如:
Map<String, String> concurrentMap = new ConcurrentHashMap<>();
ConcurrentHashMap
还引入了一些额外的并发操作方法,如 putIfAbsent()
、computeIfAbsent()
等。
CopyOnWriteArrayList
和 CopyOnWriteArraySet
CopyOnWriteArrayList
和 CopyOnWriteArraySet
是基于写时复制(Copy-On-Write)的集合类,适用于读操作远多于写操作的场景。
每次写操作都会复制底层数组,写操作性能较低,但读操作不需要加锁,性能非常高。
例如:
List<String> cowList = new CopyOnWriteArrayList<>();
Set<String> cowSet = new CopyOnWriteArraySet<>();
BlockingQueue
(如 LinkedBlockingQueue
、ArrayBlockingQueue
)BlockingQueue
是线程安全的队列实现,适用于生产者-消费者模型。它提供了阻塞的 put()
和 take()
方法,用于线程之间安全地共享数据。LinkedBlockingQueue
、ArrayBlockingQueue
等。ConcurrentSkipListMap
和 ConcurrentSkipListSet
这两个类是线程安全的、基于跳表的数据结构,它们是有序集合,可以用在需要线程安全且有序的场景中。
例如:
Map<String, String> skipListMap = new ConcurrentSkipListMap<>();
Set<String> skipListSet = new ConcurrentSkipListSet<>();
CopyOnWriteArrayList
。ConcurrentHashMap
是一个很好的选择。Collections.synchronizedXXX()
。BlockingQueue
是非常合适的选择。Java 集合类是 Java 编程中的基础工具之一,用于存储和操作一组对象。集合类提供了多种不同的数据结构和算法,包括列表、集合、映射等。下面将通过几个常见的集合类的实际应用场景,介绍它们的使用。
场景:需要存储一个可变长度的元素列表,并且对顺序进行严格的管理。
示例代码:
import java.util.ArrayList;
import java.util.List;
public class ArrayListExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
// 添加元素
list.add("Apple");
list.add("Banana");
list.add("Orange");
// 遍历列表
for (String fruit : list) {
System.out.println(fruit);
}
// 获取元素
String firstFruit = list.get(0);
System.out.println("First Fruit: " + firstFruit);
// 删除元素
list.remove("Banana");
System.out.println("After removal: " + list);
}
}
适用场景:当需要频繁读取元素且元素顺序重要时,ArrayList
是理想的选择。
场景:需要存储一组不重复的元素,并且不关心元素的顺序。
示例代码:
import java.util.HashSet;
import java.util.Set;
public class HashSetExample {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
// 添加元素
set.add("Apple");
set.add("Banana");
set.add("Orange");
set.add("Apple"); // 重复的元素不会被添加
// 遍历集合
for (String fruit : set) {
System.out.println(fruit);
}
// 判断是否包含某个元素
boolean containsApple = set.contains("Apple");
System.out.println("Contains Apple? " + containsApple);
}
}
适用场景:需要避免重复元素时,HashSet
是最佳选择。
场景:需要将一组键值对进行存储和快速检索。
示例代码:
import java.util.HashMap;
import java.util.Map;
public class HashMapExample {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
// 添加键值对
map.put("Apple", 10);
map.put("Banana", 20);
map.put("Orange", 30);
// 遍历 Map
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
// 获取特定键对应的值
int applePrice = map.get("Apple");
System.out.println("Price of Apple: " + applePrice);
// 删除键值对
map.remove("Banana");
System.out.println("After removal: " + map);
}
}
适用场景:需要通过键快速查找数据时,HashMap
是常用选择。
场景:需要频繁对集合的两端进行操作(如插入和删除)。
示例代码:
import java.util.LinkedList;
public class LinkedListExample {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
// 添加元素
list.add("Apple");
list.add("Banana");
list.addFirst("Orange"); // 在头部插入
list.addLast("Grape"); // 在尾部插入
// 遍历列表
for (String fruit : list) {
System.out.println(fruit);
}
// 删除元素
list.removeFirst(); // 删除头部
list.removeLast(); // 删除尾部
System.out.println("After removal: " + list);
}
}
适用场景:当需要频繁在列表头尾操作时,LinkedList
具有更高的性能。
场景:需要存储一组不重复且有序的元素。
示例代码:
import java.util.TreeSet;
public class TreeSetExample {
public static void main(String[] args) {
TreeSet<String> set = new TreeSet<>();
// 添加元素
set.add("Banana");
set.add("Apple");
set.add("Orange");
// 遍历集合(自动按字典顺序排序)
for (String fruit : set) {
System.out.println(fruit);
}
// 获取最小和最大元素
System.out.println("First: " + set.first());
System.out.println("Last: " + set.last());
}
}
适用场景:需要存储有序元素时,TreeSet
是理想的选择。
场景:需要按优先级顺序处理任务或元素。
示例代码:
import java.util.PriorityQueue;
public class PriorityQueueExample {
public static void main(String[] args) {
PriorityQueue<Integer> queue = new PriorityQueue<>();
// 添加元素
queue.add(10);
queue.add(20);
queue.add(5);
// 处理元素(自动按升序排列)
while (!queue.isEmpty()) {
System.out.println(queue.poll());
}
}
}
适用场景:需要按优先级处理任务时,PriorityQueue
非常适合。
Java 集合类为我们提供了多种处理不同数据需求的工具。在实际开发中,选择合适的集合类不仅可以提高程序性能,还可以让代码更加简洁和可读。