• Java高级编程技术详解:从多线程到算法优化的全面指南


    复杂度与优化

    复杂度与优化在算法中的应用

    算法复杂度是衡量算法效率的重要指标。了解和优化算法复杂度对提升程序性能非常关键。本文将介绍时间复杂度和空间复杂度的基本概念,并探讨一些优化技术。

    时间复杂度和空间复杂度

    时间复杂度表示算法执行所需时间随输入规模变化的情况,通常用大O符号表示。常见的时间复杂度有O(1)、O(log n)、O(n)、O(n log n)、O(n²)等。

    空间复杂度表示算法运行过程中占用的存储空间,常见的空间复杂度有O(1)、O(n)等。

    示例代码:计算一个数组中最大值的时间复杂度

    1. public class MaxValue {
    2. /**
    3. * 找到数组中的最大值
    4. * @param arr 输入数组
    5. * @return 数组中的最大值
    6. */
    7. public static int findMax(int[] arr) {
    8. int max = arr[0]; // 假设第一个元素是最大值
    9. for (int value : arr) { // 遍历数组
    10. if (value > max) {
    11. max = value; // 更新最大值
    12. }
    13. }
    14. return max;
    15. }
    16. public static void main(String[] args) {
    17. int[] numbers = {1, 3, 5, 7, 9};
    18. System.out.println("Max value: " + findMax(numbers)); // 输出最大值
    19. }
    20. }

    上述代码的时间复杂度为O(n),空间复杂度为O(1)。

    优化技术
    1. 减少不必要的计算:在循环中避免重复计算,尽量将不变的计算移出循环。
    2. 使用高效的数据结构:如哈希表、堆等,这些数据结构能在某些情况下显著降低时间复杂度。

    示例代码:使用哈希表优化查找

    1. import java.util.HashMap;
    2. import java.util.Map;
    3. public class FindPair {
    4. /**
    5. * 判断数组中是否存在两个元素的和等于目标值
    6. * @param arr 输入数组
    7. * @param target 目标和
    8. * @return 如果存在这样的元素,返回true;否则返回false
    9. */
    10. public static boolean hasPairWithSum(int[] arr, int target) {
    11. Map map = new HashMap<>();
    12. for (int num : arr) { // 遍历数组
    13. if (map.containsKey(target - num)) {
    14. return true; // 找到一对满足条件的元素
    15. }
    16. map.put(num, 1); // 记录当前元素
    17. }
    18. return false; // 没有找到满足条件的元素
    19. }
    20. public static void main(String[] args) {
    21. int[] numbers = {1, 3, 5, 7, 9};
    22. int target = 8;
    23. System.out.println("Pair with sum " + target + ": " + hasPairWithSum(numbers, target)); // 输出是否存在满足条件的元素
    24. }
    25. }

    上述代码的时间复杂度为O(n),空间复杂度为O(n)。

    并行与分布式算法

    Java中的并行与分布式算法

    并行和分布式算法在处理大规模数据和高性能计算中起到关键作用。本文将介绍Java中的并行处理技术和MapReduce算法。

    并行算法

    Java提供了多种并行处理的工具,包括java.util.concurrent包和Fork/Join框架。

    示例代码:Fork/Join框架

    1. import java.util.concurrent.RecursiveTask;
    2. import java.util.concurrent.ForkJoinPool;
    3. public class SumTask extends RecursiveTask {
    4. private final int[] arr;
    5. private final int start, end;
    6. /**
    7. * 构造函数,初始化待处理的数组区间
    8. * @param arr 输入数组
    9. * @param start 起始位置
    10. * @param end 结束位置
    11. */
    12. public SumTask(int[] arr, int start, int end) {
    13. this.arr = arr;
    14. this.start = start;
    15. this.end = end;
    16. }
    17. @Override
    18. protected Integer compute() {
    19. if (end - start <= 10) { // 如果任务规模小于等于10,则直接计算
    20. int sum = 0;
    21. for (int i = start; i <= end; i++) {
    22. sum += arr[i];
    23. }
    24. return sum;
    25. } else { // 否则分解任务
    26. int mid = (start + end) / 2;
    27. SumTask leftTask = new SumTask(arr, start, mid);
    28. SumTask rightTask = new SumTask(arr, mid + 1, end);
    29. leftTask.fork(); // 异步执行左子任务
    30. return rightTask.compute() + leftTask.join(); // 等待左子任务执行完毕并合并结果
    31. }
    32. }
    33. public static void main(String[] args) {
    34. int[] numbers = new int[100];
    35. for (int i = 0; i < 100; i++) {
    36. numbers[i] = i + 1;
    37. }
    38. ForkJoinPool pool = new ForkJoinPool();
    39. int sum = pool.invoke(new SumTask(numbers, 0, numbers.length - 1)); // 提交任务给ForkJoinPool执行
    40. System.out.println("Sum: " + sum); // 输出求和结果
    41. }
    42. }

    分布式算法

    MapReduce是一种分布式算法,用于处理大规模数据集。

    示例代码:简单MapReduce实现

    1. import java.util.*;
    2. import java.util.stream.Collectors;
    3. public class SimpleMapReduce {
    4. /**
    5. * Map阶段,统计文档中的单词频率
    6. * @param documents 输入文档数组
    7. * @return 单词频率的映射
    8. */
    9. public static Map map(String[] documents) {
    10. Map wordCount = new HashMap<>();
    11. for (String doc : documents) {
    12. String[] words = doc.split("\\s+");
    13. for (String word : words) {
    14. wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
    15. }
    16. }
    17. return wordCount;
    18. }
    19. /**
    20. * Reduce阶段,合并所有映射中的单词频率
    21. * @param maps 单词频率映射的列表
    22. * @return 合并后的单词频率映射
    23. */
    24. public static Map reduce(List> maps) {
    25. Map finalCount = new HashMap<>();
    26. for (Map map : maps) {
    27. for (Map.Entry entry : map.entrySet()) {
    28. finalCount.put(entry.getKey(), finalCount.getOrDefault(entry.getKey(), 0) + entry.getValue());
    29. }
    30. }
    31. return finalCount;
    32. }
    33. public static void main(String[] args) {
    34. String[] docs = {"hello world", "hello java", "java concurrency"};
    35. List> maps = Arrays.stream(docs)
    36. .map(SimpleMapReduce::map)
    37. .collect(Collectors.toList());
    38. Map result = reduce(maps);
    39. result.forEach((k, v) -> System.out.println(k + ": " + v)); // 输出合并后的单词频率
    40. }
    41. }

    图算法

    Java中的高级图算法

    图算法在解决诸如网络流、最短路径等问题时非常有用。本文将介绍一些高级图算法及其Java实现。

    网络流算法

    最大流算法用于计算网络中的最大流量。Ford-Fulkerson方法是一种经典的最大流算法。

    示例代码:Ford-Fulkerson算法

    1. import java.util.LinkedList;
    2. import java.util.Queue;
    3. public class FordFulkerson {
    4. private static final int V = 6; // 图中的顶点数
    5. /**
    6. * 使用广度优先搜索查找增广路径
    7. * @param rGraph 残余图
    8. * @param s 源点
    9. * @param t 汇点
    10. * @param parent 存储路径的数组
    11. * @return 如果存在增广路径,返回true;否则返回false
    12. */
    13. boolean bfs(int[][] rGraph, int s, int t, int[] parent) {
    14. boolean[] visited = new boolean[V];
    15. Queue queue = new LinkedList<>();
    16. queue.add(s);
    17. visited[s] = true;
    18. parent[s] = -1;
    19. while (!queue.isEmpty()) {
    20. int u = queue.poll();
    21. for (int v = 0; v < V; v++) {
    22. if (!visited[v] && rGraph[u][v] > 0) {
    23. queue.add(v);
    24. parent[v] = u;
    25. visited[v] = true;
    26. }
    27. }
    28. }
    29. return visited[t];
    30. }
    31. /**
    32. * 使用Ford-Fulkerson算法计算最大流量
    33. * @param graph 输入图
    34. * @param s 源点
    35. * @param t 汇点
    36. * @return 最大流量
    37. */
    38. int fordFulkerson(int[][] graph, int s, int t) {
    39. int[][] rGraph = new int[V][V]; // 残余图
    40. for (int u = 0; u < V; u++) {
    41. for (int v = 0; v < V; v++) {
    42. rGraph[u][v] = graph[u][v];
    43. }
    44. }
    45. int[] parent = new int[V];
    46. int maxFlow = 0;
    47. while (bfs(rGraph, s, t, parent)) {
    48. int pathFlow = Integer.MAX_VALUE;
    49. for (int v = t; v != s; v = parent[v]) {
    50. int u = parent[v];
    51. pathFlow = Math.min(pathFlow, rGraph[u][v]);
    52. }
    53. for (int v = t; v != s; v = parent[v]) {
    54. int u = parent[v];
    55. rGraph[u][v] -= pathFlow;
    56. rGraph[v][u] += pathFlow;
    57. }
    58. maxFlow += pathFlow;
    59. }
    60. return maxFlow;
    61. }
    62. public static void main(String[] args) {
    63. int[][] graph = {
    64. {0, 16, 13, 0, 0, 0},
    65. {0, 0, 10, 12, 0, 0},
    66. {0, 4, 0, 0, 14, 0},
    67. {0, 0, 9, 0, 0, 20},
    68. {0, 0, 0, 7, 0, 4},
    69. {0, 0, 0, 0, 0, 0}
    70. };
    71. FordFulkerson ff = new FordFulkerson();
    72. System.out.println("Maximum flow: " + ff.fordFulkerson(graph, 0, 5)); // 输出最大流量
    73. }
    74. }
    最短路径算法

    Dijkstra算法用于计算图中从源点到其他顶点的最短路径。

    示例代码:Dijkstra算法

    1. import java.util.Arrays;
    2. import java.util.PriorityQueue;
    3. public class Dijkstra {
    4. private static final int V = 9;
    5. /**
    6. * 使用Dijkstra算法计算最短路径
    7. * @param graph 输入图
    8. * @param src 源点
    9. */
    10. void dijkstra(int[][] graph, int src) {
    11. int[] dist = new int[V];
    12. boolean[] sptSet = new boolean[V];
    13. Arrays.fill(dist, Integer.MAX_VALUE);
    14. dist[src] = 0;
    15. PriorityQueue pq = new PriorityQueue<>(V, (a, b) -> a.cost - b.cost);
    16. pq.add(new Node(src, 0));
    17. while (!pq.isEmpty()) {
    18. int u = pq.poll().vertex;
    19. sptSet[u] = true;
    20. for (int v = 0; v < V; v++) {
    21. if (!sptSet[v] && graph[u][v] != 0 && dist[u] != Integer.MAX_VALUE && dist[u] + graph[u][v] < dist[v]) {
    22. dist[v] = dist[u] + graph[u][v];
    23. pq.add(new Node(v, dist[v]));
    24. }
    25. }
    26. }
    27. printSolution(dist);
    28. }
    29. /**
    30. * 打印最短路径结果
    31. * @param dist 最短路径数组
    32. */
    33. void printSolution(int[] dist) {
    34. System.out.println("Vertex\tDistance from Source");
    35. for (int i = 0; i < V; i++) {
    36. System.out.println(i + "\t" + dist[i]);
    37. }
    38. }
    39. public static void main(String[] args) {
    40. int[][] graph = {
    41. {0, 4, 0, 0, 0, 0, 0, 8, 0},
    42. {4, 0, 8, 0, 0, 0, 0, 11, 0},
    43. {0, 8, 0, 7, 0, 4, 0, 0, 2},
    44. {0, 0, 7, 0, 9, 14, 0, 0, 0},
    45. {0, 0, 0, 9, 0, 10, 0, 0, 0},
    46. {0, 0, 4, 14, 10, 0, 2, 0, 0},
    47. {0, 0, 0, 0, 0, 2, 0, 1, 6},
    48. {8, 11, 0, 0, 0, 0, 1, 0, 7},
    49. {0, 0, 2, 0, 0, 0, 6, 7, 0}
    50. };
    51. Dijkstra dijkstra = new Dijkstra();
    52. dijkstra.dijkstra(graph, 0); // 从源点0计算最短路径
    53. }
    54. class Node {
    55. int vertex;
    56. int cost;
    57. public Node(int vertex, int cost) {
    58. this.vertex = vertex;
    59. this.cost = cost;
    60. }
    61. }
    62. }

    机器学习与深度学习

    Java中的机器学习与深度学习

    机器学习和深度学习在现代数据分析中非常重要。本文将介绍如何在Java中实现简单的神经网络,以及如何使用DL4J进行深度学习。

    简单的神经网络

    一个简单的神经网络可以通过矩阵运算实现。

    示例代码:简单的神经网络实现

    1. import java.util.Random;
    2. public class SimpleNeuralNetwork {
    3. private final double[][] weights;
    4. /**
    5. * 构造函数,初始化神经网络的权重
    6. * @param inputSize 输入层大小
    7. * @param outputSize 输出层大小
    8. */
    9. public SimpleNeuralNetwork(int inputSize, int outputSize) {
    10. weights = new double[inputSize][outputSize];
    11. Random rand = new Random();
    12. for (int i = 0; i < inputSize; i++) {
    13. for (int j = 0; j < outputSize; j++) {
    14. weights[i][j] = rand.nextDouble();
    15. }
    16. }
    17. }
    18. /**
    19. * 预测函数,计算输出
    20. * @param inputs 输入数据
    21. * @return 输出数据
    22. */
    23. public double[] predict(double[] inputs) {
    24. double[] outputs = new double[weights[0].length];
    25. for (int i = 0; i < weights[0].length; i++) {
    26. outputs[i] = 0;
    27. for (int j = 0; j < weights.length; j++) {
    28. outputs[i] += inputs[j] * weights[j][i];
    29. }
    30. }
    31. return outputs;
    32. }
    33. public static void main(String[] args) {
    34. SimpleNeuralNetwork nn = new SimpleNeuralNetwork(3, 2);
    35. double[] inputs = {1.0, 0.5, -1.0};
    36. double[] outputs = nn.predict(inputs);
    37. for (double output : outputs) {
    38. System.out.println(output);
    39. }
    40. }
    41. }
    使用DL4J进行深度学习

    DL4J(Deeplearning4j)是Java中流行的深度学习库。下面的代码展示了如何使用DL4J训练一个简单的神经网络。

    示例代码:使用DL4J进行深度学习

    1. import org.deeplearning4j.datasets.iterator.impl.MnistDataSetIterator;
    2. import org.deeplearning4j.nn.api.OptimizationAlgorithm;
    3. import org.deeplearning4j.nn.conf.MultiLayerConfiguration;
    4. import org.deeplearning4j.nn.conf.NeuralNetConfiguration;
    5. import org.deeplearning4j.nn.conf.layers.DenseLayer;
    6. import org.deeplearning4j.nn.conf.layers.OutputLayer;
    7. import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
    8. import org.deeplearning4j.optimize.api.IterationListener;
    9. import org.deeplearning4j.optimize.listeners.ScoreIterationListener;
    10. import org.nd4j.linalg.api.ndarray.INDArray;
    11. import org.nd4j.linalg.dataset.api.iterator.DataSetIterator;
    12. import org.nd4j.linalg.factory.Nd4j;
    13. import org.nd4j.linalg.learning.config.Sgd;
    14. import org.nd4j.linalg.lossfunctions.LossFunctions;
    15. public class DL4JExample {
    16. public static void main(String[] args) throws Exception {
    17. int inputSize = 784;
    18. int outputSize = 10;
    19. int batchSize = 128;
    20. int epochs = 5;
    21. DataSetIterator mnistTrain = new MnistDataSetIterator(batchSize, true, 12345);
    22. MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
    23. .seed(123)
    24. .optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
    25. .updater(new Sgd(0.1))
    26. .list()
    27. .layer(new DenseLayer.Builder().nIn(inputSize).nOut(1000).activation("relu").build())
    28. .layer(new OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD)
    29. .nIn(1000).nOut(outputSize).activation("softmax").build())
    30. .build();
    31. MultiLayerNetwork model = new MultiLayerNetwork(conf);
    32. model.init();
    33. model.setListeners(new ScoreIterationListener(10));
    34. for (int i = 0; i < epochs; i++) {
    35. model.fit(mnistTrain);
    36. }
    37. // 评估模型性能
    38. DataSetIterator mnistTest = new MnistDataSetIterator(batchSize, false, 12345);
    39. Evaluation eval = new Evaluation(outputSize);
    40. while (mnistTest.hasNext()) {
    41. DataSet ds = mnistTest.next();
    42. INDArray output = model.output(ds.getFeatureMatrix());
    43. eval.eval(ds.getLabels(), output);
    44. }
    45. System.out.println(eval.stats());
    46. }
    47. }

  • 相关阅读:
    python容器之字典
    C++核心编程(十四)this指针的本质,常函数,常对象的注意事项
    人工智能对建筑学的影响,关于智能建筑的论文
    附幻灯片下载|图解国标《网络数据分类分级要求(征)》
    熬夜万字肝爆Redis知识总结,全网最全
    学习:原码-反码-补码
    文件I/O与标准I/O
    本着什么原则,才能写出优秀的代码?
    002 IOC和DI使用
    javaWeb—JavaScript
  • 原文地址:https://blog.csdn.net/qq_41434431/article/details/139738286