Java常用算法深度解析:从集合框架到并发编程

目录

一、Java算法生态:集合框架与流式编程

[1.1 Java算法的演进历程](#1.1 Java算法的演进历程)

[1.2 集合框架中的算法](#1.2 集合框架中的算法)

[二、Stream API:声明式算法编程](#二、Stream API:声明式算法编程)

[2.1 Stream操作的三阶段](#2.1 Stream操作的三阶段)

[2.2 高级Stream操作](#2.2 高级Stream操作)

三、排序与搜索算法

[3.1 对象排序的多种方式](#3.1 对象排序的多种方式)

[3.2 搜索算法实现](#3.2 搜索算法实现)

四、数值计算与统计

[4.1 基本数值算法](#4.1 基本数值算法)

[4.2 统计与聚合算法](#4.2 统计与聚合算法)

五、字符串处理算法

[5.1 字符串匹配与操作](#5.1 字符串匹配与操作)

六、并发与并行算法

[6.1 并行流与Fork/Join框架](#6.1 并行流与Fork/Join框架)

[6.2 并发集合算法](#6.2 并发集合算法)

七、图算法实现

[7.1 图的表示与遍历](#7.1 图的表示与遍历)

八、设计模式在算法中的应用

[8.1 策略模式实现排序算法](#8.1 策略模式实现排序算法)


如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

一、Java算法生态:集合框架与流式编程

1.1 Java算法的演进历程

Java算法设计经历了三个重要阶段:

  • JDK 1.2:Collections Framework引入,奠定算法基础
  • JDK 5:泛型、并发集合、增强for循环
  • JDK 8:Stream API、Lambda表达式、函数式编程革命

1.2 集合框架中的算法

// Collections工具类中的静态算法方法

List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6);

// 1. 排序算法

Collections.sort(numbers); // 升序排序

Collections.sort(numbers, Collections.reverseOrder()); // 降序排序

Collections.shuffle(numbers); // 随机打乱

// 2. 查找算法

int index = Collections.binarySearch(numbers, 5); // 二分查找

int freq = Collections.frequency(numbers, 1); // 出现频率

// 3. 极值算法

Integer max = Collections.max(numbers);

Integer min = Collections.min(numbers);

// 4. 不可变集合

List<Integer> unmodifiable = Collections.unmodifiableList(numbers);

Set<Integer> singleton = Collections.singleton(42);

List<Integer> nCopies = Collections.nCopies(5, 0); // 0, 0, 0, 0, 0

二、Stream API:声明式算法编程

2.1 Stream操作的三阶段

// 创建 → 中间操作 → 终止操作

List<Integer> result = numbers.stream() // 创建流

.filter(n -> n % 2 == 0) // 中间操作:过滤

.map(n -> n * n) // 中间操作:映射

.sorted((a, b) -> b - a) // 中间操作:排序

.distinct() // 中间操作:去重

.limit(3) // 中间操作:限制

.collect(Collectors.toList()); // 终止操作:收集

// 并行流加速处理

long count = numbers.parallelStream()

.filter(n -> isPrime(n))

.count();

2.2 高级Stream操作

// 1. 分组与分区

Map<String, List<Employee>> byDept = employees.stream()

.collect(Collectors.groupingBy(Employee::getDepartment));

Map<Boolean, List<Employee>> partitioned = employees.stream()

.collect(Collectors.partitioningBy(e -> e.getSalary() > 50000));

// 2. 统计汇总

IntSummaryStatistics stats = employees.stream()

.mapToInt(Employee::getSalary)

.summaryStatistics();

// 包含:count, sum, min, max, average

// 3. 连接字符串

String names = employees.stream()

.map(Employee::getName)

.collect(Collectors.joining(", ", "", ""));

// 4. 归约操作

Optional<Integer> total = numbers.stream()

.reduce((a, b) -> a + b); // 求和

Integer sum = numbers.stream()

.reduce(0, Integer::sum); // 带初始值的求和

// 5. 自定义收集器

Collector<Employee, ?, Map<String, Double>> avgSalaryByDept =

Collectors.groupingBy(

Employee::getDepartment,

Collectors.averagingDouble(Employee::getSalary)

);

三、排序与搜索算法

3.1 对象排序的多种方式

// 1. 实现Comparable接口

class Person implements Comparable<Person> {

private String name;

private int age;

@Override

public int compareTo(Person other) {

return Integer.compare(this.age, other.age);

}

}

// 2. 使用Comparator(更灵活)

Comparator<Person> byName = Comparator.comparing(Person::getName);

Comparator<Person> byAge = Comparator.comparingInt(Person::getAge);

Comparator<Person> byNameThenAge =

Comparator.comparing(Person::getName)

.thenComparingInt(Person::getAge);

// 3. 复杂排序

List<Person> sorted = people.stream()

.sorted(Comparator

.comparing(Person::getLastName)

.thenComparing(Person::getFirstName)

.reversed())

.collect(Collectors.toList());

// 4. 处理null值

Comparator<Person> nullsFirst =

Comparator.nullsFirst(Comparator.naturalOrder());

3.2 搜索算法实现

// 1. 二分查找(数组必须有序)

int\[\] sortedArray = {1, 3, 5, 7, 9, 11, 13};

int index = Arrays.binarySearch(sortedArray, 7); // 返回3

// 2. 自定义二分查找

public static <T> int binarySearch(List<? extends T> list, T key,

Comparator<? super T> c) {

int low = 0;

int high = list.size() - 1;

while (low <= high) {

int mid = (low + high) >>> 1; // 无符号右移,防止溢出

T midVal = list.get(mid);

int cmp = c.compare(midVal, key);

if (cmp < 0) {

low = mid + 1;

} else if (cmp > 0) {

high = mid - 1;

} else {

return mid; // 找到

}

}

return -(low + 1); // 未找到,返回插入点

}

// 3. 使用Collections.binarySearch

List<String> words = Arrays.asList("apple", "banana", "cherry", "date");

int pos = Collections.binarySearch(words, "cherry");

四、数值计算与统计

4.1 基本数值算法

// 1. 使用Math类

double sqrt = Math.sqrt(16.0); // 4.0

double pow = Math.pow(2, 10); // 1024.0

double sin = Math.sin(Math.PI / 2); // 1.0

long round = Math.round(3.14159); // 3

// 2. 随机数生成

Random random = new Random();

int randomInt = random.nextInt(100); // 0-99

double randomDouble = random.nextDouble(); // 0.0-1.0

// 3. 安全的随机数(密码学安全)

SecureRandom secureRandom = new SecureRandom();

byte\[\] randomBytes = new byte16;

secureRandom.nextBytes(randomBytes);

// 4. 大数计算

BigInteger bigInt = new BigInteger("12345678901234567890");

BigInteger result = bigInt.multiply(new BigInteger("2"));

BigDecimal decimal1 = new BigDecimal("10.50");

BigDecimal decimal2 = new BigDecimal("3.75");

BigDecimal division = decimal1.divide(decimal2, 4, RoundingMode.HALF_UP);

4.2 统计与聚合算法

// 1. 基本统计

public class Statistics {

public static double mean(double\[\] values) {

return Arrays.stream(values).average().orElse(0.0);

}

public static double median(double\[\] values) {

double\[\] sorted = values.clone();

Arrays.sort(sorted);

int n = sorted.length;

if (n % 2 == 0) {

return (sortedn/2 - 1 + sortedn/2) / 2.0;

} else {

return sortedn/2;

}

}

public static double standardDeviation(double\[\] values) {

double mean = mean(values);

double variance = Arrays.stream(values)

.map(x -> Math.pow(x - mean, 2))

.average().orElse(0.0);

return Math.sqrt(variance);

}

}

// 2. 使用DoubleSummaryStatistics

DoubleSummaryStatistics stats = Arrays.stream(new double\[\]{1.0, 2.0, 3.0, 4.0})

.summaryStatistics();

// 3. 移动平均

public static double\[\] movingAverage(double\[\] data, int window) {

double\[\] result = new doubledata.length - window + 1;

double sum = 0;

for (int i = 0; i < window; i++) {

sum += datai;

}

result0 = sum / window;

for (int i = window; i < data.length; i++) {

sum = sum - datai - window + datai;

resulti - window + 1 = sum / window;

}

return result;

}

五、字符串处理算法

5.1 字符串匹配与操作

// 1. KMP字符串匹配算法

public class KMP {

public static int search(String text, String pattern) {

int\[\] lps = computeLPS(pattern);

int i = 0, j = 0;

while (i < text.length()) {

if (text.charAt(i) == pattern.charAt(j)) {

i++;

j++;

if (j == pattern.length()) {

return i - j;

}

} else {

if (j != 0) {

j = lpsj - 1;

} else {

i++;

}

}

}

return -1;

}

private static int\[\] computeLPS(String pattern) {

int\[\] lps = new intpattern.length();

int len = 0, i = 1;

while (i < pattern.length()) {

if (pattern.charAt(i) == pattern.charAt(len)) {

len++;

lpsi = len;

i++;

} else {

if (len != 0) {

len = lpslen - 1;

} else {

lpsi = 0;

i++;

}

}

}

return lps;

}

}

// 2. 字符串编辑距离(动态规划)

public static int editDistance(String word1, String word2) {

int m = word1.length();

int n = word2.length();

int\[\]\[\] dp = new intm + 1n + 1;

for (int i = 0; i <= m; i++) dpi0 = i;

for (int j = 0; j <= n; j++) dp0j = j;

for (int i = 1; i <= m; i++) {

for (int j = 1; j <= n; j++) {

if (word1.charAt(i - 1) == word2.charAt(j - 1)) {

dpij = dpi - 1j - 1;

} else {

dpij = 1 + Math.min(

dpi - 1j - 1, // 替换

Math.min(

dpi - 1j, // 删除

dpij - 1 // 插入

)

);

}

}

}

return dpmn;

}

// 3. 使用StringBuilder优化字符串操作

public static String reverseString(String s) {

return new StringBuilder(s).reverse().toString();

}

public static boolean isPalindrome(String s) {

String cleaned = s.replaceAll("\^a-zA-Z0-9", "").toLowerCase();

return cleaned.equals(new StringBuilder(cleaned).reverse().toString());

}

六、并发与并行算法

6.1 并行流与Fork/Join框架

// 1. 并行流计算

long sum = LongStream.rangeClosed(1, 10_000_000)

.parallel()

.sum();

// 2. 自定义Fork/Join任务

class SumTask extends RecursiveTask<Long> {

private static final int THRESHOLD = 10_000;

private final long\[\] array;

private final int start, end;

SumTask(long\[\] array, int start, int end) {

this.array = array;

this.start = start;

this.end = end;

}

@Override

protected Long compute() {

if (end - start <= THRESHOLD) {

long sum = 0;

for (int i = start; i < end; i++) {

sum += arrayi;

}

return sum;

} else {

int mid = (start + end) / 2;

SumTask left = new SumTask(array, start, mid);

SumTask right = new SumTask(array, mid, end);

left.fork();

long rightResult = right.compute();

long leftResult = left.join();

return leftResult + rightResult;

}

}

}

// 使用Fork/Join池

ForkJoinPool pool = new ForkJoinPool();

long\[\] numbers = new long100_000;

// 填充数组...

SumTask task = new SumTask(numbers, 0, numbers.length);

long result = pool.invoke(task);

6.2 并发集合算法

// 1. ConcurrentHashMap的原子操作

ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

// 线程安全的更新

map.compute("key", (k, v) -> v == null ? 1 : v + 1);

// 原子操作

map.merge("key", 1, Integer::sum);

// 2. CopyOnWriteArrayList(读多写少场景)

CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();

list.add("item1");

list.addIfAbsent("item1"); // 不会重复添加

// 3. 阻塞队列算法

BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);

// 生产者

new Thread(() -> {

try {

for (int i = 0; i < 100; i++) {

queue.put(i); // 阻塞直到有空间

Thread.sleep(100);

}

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

}).start();

// 消费者

new Thread(() -> {

try {

while (true) {

Integer item = queue.take(); // 阻塞直到有元素

System.out.println("Consumed: " + item);

}

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

}

}).start();

七、图算法实现

7.1 图的表示与遍历

// 1. 邻接表表示

class Graph {

private final int V;

private final List<List<Integer>> adj;

public Graph(int V) {

this.V = V;

adj = new ArrayList<>(V);

for (int i = 0; i < V; i++) {

adj.add(new ArrayList<>());

}

}

public void addEdge(int v, int w) {

adj.get(v).add(w);

}

// 深度优先搜索

public void dfs(int start) {

boolean\[\] visited = new booleanV;

Stack<Integer> stack = new Stack<>();

stack.push(start);

while (!stack.isEmpty()) {

int v = stack.pop();

if (!visitedv) {

visitedv = true;

System.out.print(v + " ");

for (int neighbor : adj.get(v)) {

if (!visitedneighbor) {

stack.push(neighbor);

}

}

}

}

}

// 广度优先搜索

public void bfs(int start) {

boolean\[\] visited = new booleanV;

Queue<Integer> queue = new LinkedList<>();

visitedstart = true;

queue.offer(start);

while (!queue.isEmpty()) {

int v = queue.poll();

System.out.print(v + " ");

for (int neighbor : adj.get(v)) {

if (!visitedneighbor) {

visitedneighbor = true;

queue.offer(neighbor);

}

}

}

}

}

// 2. Dijkstra最短路径算法

public class Dijkstra {

public static int\[\] dijkstra(int\[\]\[\] graph, int src) {

int V = graph.length;

int\[\] dist = new intV;

boolean\[\] sptSet = new booleanV;

Arrays.fill(dist, Integer.MAX_VALUE);

distsrc = 0;

for (int count = 0; count < V - 1; count++) {

int u = minDistance(dist, sptSet);

sptSetu = true;

for (int v = 0; v < V; v++) {

if (!sptSetv && graphuv != 0 &&

distu != Integer.MAX_VALUE &&

distu + graphuv < distv) {

distv = distu + graphuv;

}

}

}

return dist;

}

private static int minDistance(int\[\] dist, boolean\[\] sptSet) {

int min = Integer.MAX_VALUE, minIndex = -1;

for (int v = 0; v < dist.length; v++) {

if (!sptSetv && distv <= min) {

min = distv;

minIndex = v;

}

}

return minIndex;

}

}

八、设计模式在算法中的应用

8.1 策略模式实现排序算法

// 策略接口

interface SortStrategy {

void sort(int\[\] array);

}

// 具体策略

class BubbleSortStrategy implements SortStrategy {

@Override

public void sort(int\[\] array) {

// 冒泡排序实现

for (int i = 0; i < array.length - 1; i++) {

for (int j = 0; j < array.length - i - 1; j++) {

if (arrayj > arrayj + 1) {

int temp = arrayj;

arrayj = arrayj + 1;

arrayj + 1 = temp;

}

}

}

}

}

class QuickSortStrategy implements SortStrategy {

@Override

public void sort(int\[\] array) {

quickSort(array, 0, array.length - 1);

}

private void quickSort(int\[\] array, int low, int high) {

if (low < high) {

int pi = partition(array, low, high);

quickSort(array, low, pi - 1);

quickSort(array, pi + 1, high);

}

}

private int partition(int\[\] array, int low, int high) {

int pivot = arrayhigh;

int i = low - 1;

for (int j = low; j < high; j++) {

if (arrayj < pivot) {

i++;

swap(array, i, j);

}

}

swap(array, i + 1, high);

return i + 1;

}

private void swap(int\[\] array, int i, int j) {

int temp = arrayi;

arrayi = arrayj;

arrayj = temp;

}

}

// 上下文类

class Sorter {

private SortStrategy strategy;

public Sorter(SortStrategy strategy) {

this.strategy = strategy;

}

public void setStrategy(SortStrategy strategy) {

this.strategy = strategy;

}

public void sort(int\[\] array) {

strategy.sort(array);

}

}

// 使用示例

public class StrategyPatternDemo {

public static void main(String\[\] args) {

int\[\] array = {5, 2, 8, 1, 9, 3};

Sorter sorter = new Sorter(new BubbleSortStrategy());

sorter.sort(array);

System.out.println("Bubble sort: " + Arrays.toString(array));

sorter.setStrategy(new QuickSortStrategy());

sorter.sort(array);

System.out.println("Quick sort: " + Arrays.toString(array));

}

}

Java算法生态的丰富性使得开发者可以根据具体场景选择最合适的工具。从传统的集合框架到现代的Stream API,从单线程算法到并发编程,Java提供了完整的算法工具箱。掌握这些算法不仅能够提高代码效率,还能写出更优雅、更易维护的程序。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

相关推荐
小雨下雨的雨3 小时前
井字棋AI机器人实现详解 - Minimax算法实战-鸿蒙PC Electron框架完成
前端·人工智能·算法·华为·electron·鸿蒙
xieliyu.6 小时前
Java算法精讲:双指针(三)
java·开发语言·算法
明夜之约6 小时前
Spring Boot 自动装配源码
java·spring boot·后端
Leaton Lee6 小时前
Spring Boot分层架构详解:从Controller到Service再到Mapper的完整流程
java·spring boot·后端·架构
Jinkxs6 小时前
Resilience4j- 与 Spring Boot 快速集成:自动配置与基础注解使用
java·spring boot·后端
辣机小司6 小时前
【踩坑记录:Spring Boot 配置文件读取值不一致?警惕 YAML 的“八进制陷阱”与 SnakeYAML 版本之谜】
java·spring boot·后端·yaml·踩坑记录
一条小锦吕*6 小时前
基于Spring Boot + 数据可视化 + 协同过滤算法的推荐系统设计与实现(源码+论文+部署全讲解)
spring boot·算法·信息可视化
fangdengfu1237 小时前
ES分析系统各个服务日志占用量
java·前端·elasticsearch
云烟成雨TD7 小时前
Spring AI 1.x 系列【51】可观测性技术选型
java·人工智能·spring
星越华夏7 小时前
ESP32-CAM图像传输项目说明文档
java·后端·struts·esp32