# Java 集合框架
集合框架是Java中用于存储和处理对象组的统一架构,提供了一系列标准的接口和类来实现常用的数据结构。
# List接口
List是有序集合,允许重复元素。
# ArrayList
// 创建ArrayList
ArrayList<String> list = new ArrayList<>();
// 添加元素
list.add("苹果");
list.add("香蕉");
list.add("橙子");
// 访问元素
String fruit = list.get(0); // 获取第一个元素
// 修改元素
list.set(1, "葡萄");
// 删除元素
list.remove("橙子"); // 按对象删除
list.remove(0); // 按索引删除
// 遍历列表
for (String item : list) {
System.out.println(item);
}
# LinkedList
// 创建LinkedList
LinkedList<Integer> numbers = new LinkedList<>();
// 添加元素
numbers.add(1);
numbers.addFirst(0); // 在开头添加
numbers.addLast(2); // 在末尾添加
// 获取元素
int first = numbers.getFirst();
int last = numbers.getLast();
// 删除元素
numbers.removeFirst();
numbers.removeLast();
# Set接口
Set是不允许重复元素的集合。
# HashSet
// 创建HashSet
HashSet<String> set = new HashSet<>();
// 添加元素
set.add("Java");
set.add("Python");
set.add("JavaScript");
// 检查元素
boolean exists = set.contains("Java");
// 删除元素
set.remove("Python");
// 遍历集合
for (String language : set) {
System.out.println(language);
}
# TreeSet
// 创建TreeSet(元素会自动排序)
TreeSet<Integer> numbers = new TreeSet<>();
// 添加元素
numbers.add(5);
numbers.add(2);
numbers.add(8);
// 获取最大最小值
int min = numbers.first();
int max = numbers.last();
// 获取子集
SortedSet<Integer> subset = numbers.subSet(2, 8);
# Map接口
Map用于存储键值对。
# HashMap
// 创建HashMap
HashMap<String, Integer> scores = new HashMap<>();
// 添加键值对
scores.put("张三", 95);
scores.put("李四", 88);
scores.put("王五", 92);
// 获取值
int score = scores.get("张三");
// 检查键是否存在
boolean hasKey = scores.containsKey("李四");
// 遍历Map
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
# TreeMap
// 创建TreeMap(键会自动排序)
TreeMap<String, Double> prices = new TreeMap<>();
// 添加键值对
prices.put("香蕉", 5.5);
prices.put("苹果", 8.0);
prices.put("橙子", 6.5);
// 获取第一个和最后一个键值对
Map.Entry<String, Double> first = prices.firstEntry();
Map.Entry<String, Double> last = prices.lastEntry();
# 集合工具类
# Collections类
// 排序
List<Integer> numbers = new ArrayList<>();
numbers.add(3);
numbers.add(1);
numbers.add(2);
Collections.sort(numbers);
// 二分查找
int index = Collections.binarySearch(numbers, 2);
// 最大最小值
int max = Collections.max(numbers);
int min = Collections.min(numbers);
// 反转
Collections.reverse(numbers);
// 打乱
Collections.shuffle(numbers);
# 实践案例
# 学生成绩管理系统
public class Student {
private String name;
private Map<String, Integer> scores;
public Student(String name) {
this.name = name;
this.scores = new HashMap<>();
}
public void addScore(String subject, int score) {
scores.put(subject, score);
}
public double getAverage() {
if (scores.isEmpty()) return 0;
int sum = 0;
for (int score : scores.values()) {
sum += score;
}
return (double) sum / scores.size();
}
}
// 使用示例
List<Student> students = new ArrayList<>();
Student student = new Student("张三");
student.addScore("数学", 95);
student.addScore("英语", 88);
students.add(student);
# 练习
- 实现一个简单的购物车系统,使用合适的集合类存储商品信息
- 创建一个电话簿应用,支持按姓名查找电话号码
- 实现一个任务管理器,可以按优先级对任务进行排序
# 进阶特性
# 1. 泛型编程
# 泛型集合类的使用技巧
// 使用通配符上界
public static double sumOfList(List<? extends Number> list) {
double sum = 0.0;
for (Number n : list) {
sum += n.doubleValue();
}
return sum;
}
// 使用通配符下界
public static void addNumbers(List<? super Integer> list) {
for (int i = 1; i <= 5; i++) {
list.add(i);
}
}
// 类型边界示例
public class Box<T extends Comparable<T>> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public boolean isGreaterThan(Box<T> other) {
return value.compareTo(other.getValue()) > 0;
}
}
# 自定义泛型方法和类
// 泛型方法
public class Util {
public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
return p1.getKey().equals(p2.getKey()) &&
p1.getValue().equals(p2.getValue());
}
}
// 泛型类
public class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() { return key; }
public V getValue() { return value; }
}
# 2. Stream API
# 流操作基础
// 基本流操作
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// 过滤和映射
List<String> filteredNames = names.stream()
.filter(name -> name.length() > 4)
.map(String::toUpperCase)
.collect(Collectors.toList());
// 聚合操作
int sum = Stream.of(1, 2, 3, 4, 5)
.reduce(0, Integer::sum);
// 分组操作
Map<Integer, List<String>> groupedByLength = names.stream()
.collect(Collectors.groupingBy(String::length));
# 并行流处理
// 并行流示例
long count = names.parallelStream()
.filter(name -> name.length() > 4)
.count();
// 自定义收集器
public class CustomCollector {
public static <T> Collector<T, ?, List<List<T>>> partitionBySize(int size) {
return Collectors.collectingAndThen(
Collectors.toList(),
list -> {
int chunk = Math.min(size, list.size());
return IntStream.range(0, (list.size() + chunk - 1) / chunk)
.mapToObj(i -> list.subList(i * chunk, Math.min(list.size(), (i + 1) * chunk)))
.collect(Collectors.toList());
}
);
}
}
# 3. 并发集合
# ConcurrentHashMap的使用
// ConcurrentHashMap基本操作
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
// 原子操作
map.computeIfAbsent("count", k -> 0);
map.computeIfPresent("count", (k, v) -> v + 1);
// 并发遍历
map.forEach(1, (key, value) ->
System.out.println(key + ": " + value));
// 聚合操作
Integer maxValue = map.reduceValues(1, Integer::max);
# CopyOnWriteArrayList应用
// 创建线程安全的List
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
// 多线程环境下的操作
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 0; i < 3; i++) {
executor.submit(() -> {
list.add("Item " + System.currentTimeMillis());
// 遍历时不会抛出ConcurrentModificationException
for (String item : list) {
System.out.println(item);
}
});
}
# 阻塞队列示例
// 生产者-消费者模式
class ProducerConsumer {
private BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
class Producer implements Runnable {
public void run() {
try {
String data = "Task " + System.nanoTime();
queue.put(data);
System.out.println("Produced: " + data);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
class Consumer implements Runnable {
public void run() {
try {
String data = queue.take();
System.out.println("Consumed: " + data);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
# 4. 自定义集合类
# 实现Collection接口
// 自定义集合类
public class CircularBuffer<E> implements Collection<E> {
private final E[] buffer;
private int head = 0;
private int tail = 0;
private int size = 0;
@SuppressWarnings("unchecked")
public CircularBuffer(int capacity) {
buffer = (E[]) new Object[capacity];
}
@Override
public boolean add(E e) {
if (size == buffer.length) {
return false;
}
buffer[tail] = e;
tail = (tail + 1) % buffer.length;
size++;
return true;
}
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
private int current = head;
private int count = 0;
@Override
public boolean hasNext() {
return count < size;
}
@Override
public E next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
E item = buffer[current];
current = (current + 1) % buffer.length;
count++;
return item;
}
};
}
// 其他Collection接口方法的实现...
}
# 性能优化技巧
// 优化的ArrayList实现
public class OptimizedArrayList<E> extends ArrayList<E> {
private static final int DEFAULT_BATCH_SIZE = 100;
// 批量添加优化
public void addAll(Collection<? extends E> c, int batchSize) {
int remaining = c.size();
Iterator<? extends E> it = c.iterator();
while (remaining > 0) {
int batch = Math.min(remaining, batchSize);
List<E> temp = new ArrayList<>(batch);
for (int i = 0; i < batch && it.hasNext(); i++) {
temp.add(it.next());
}
super.addAll(temp);
remaining -= batch;
}
}
// 并行操作优化
public void parallelSort(Comparator<? super E> comparator) {
Object[] elements = this.toArray();
Arrays.parallelSort(elements, (Comparator) comparator);
ListIterator<E> it = this.listIterator();
for (Object e : elements) {
it.next();
it.set((E) e);
}
}
}
以上代码示例展示了Java集合框架的进阶特性,包括泛型编程、Stream API的使用、并发集合的应用以及自定义集合类的实现。这些示例涵盖了实际开发中常见的场景,并提供了性能优化的最佳实践。建议读者在理解这些概念的基础上,结合实际项目需求进行实践和应用。