Java中数组的实际经典案例

简介: Java中数组的实际经典案例

数组不仅是Java中学习的重点,也是数据结构与算法中学习的重点,我们不仅要熟悉它,也要懂得运用它。


1. 数组的拷贝


数组的拷贝分为两种,一种是对值得拷贝,一种是对地址的拷贝。

上一章中我们已经知道了数组是储存在堆上的,在栈上new出来的只是一个局部变量,用于储存堆山的地址。

上代码:

import java.util.Arrays;
public class demo {
    public static int[] copyArray(int[] arr){
        int[] copyArr = arr;
        return copyArr;
    }
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6};
        System.out.println(Arrays.toString(copyArray(arr)));
    }
}


b4ef4d4898ca45978ff2fdd6e238195b.png


两个变量同时存储同一个地址。


f4c5e13b26ae42979c0c48604b914ef9.png

import java.util.Arrays;
public class demo {
    public static int[] copyArray(int[] arr){
        int[] copyArr = new int[arr.length];
        copyArr = arr;
        return copyArr;
    }
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6};
        System.out.println(Arrays.toString(copyArray(arr)));
    }
}

374878b8da0a49219580ca7c8c18f573.png



总结:只要是new出来的都是一个新地址。


2.查找数组中指定元素(二分查找)


针对有序数组, 可以使用更高效的二分查找


啥叫有序数组?

有序分为 " 升序 " 和 " 降序 "

如 1 2 3 4 , 依次递增即为升序 .

如 4 3 2 1 , 依次递减即为降序


那么顺序查找可不可以呢?

当然是可行的,但是如果数组非常大,我们需要找的值在后面,那就会造成速度非常慢,效果非常差。

那可以选择用二分查找(也可以选择其他 更快更有效的算法)。


思路分析:


以升序数组为例, 二分查找的思路是先取中间位置的元素, 然后使用待查找元素与数组中间元素进行比较:

如果相等,即找到了返回该元素在数组中的下标

如果小于,以类似方式到数组左半侧查找

如果大于,以类似方式到数组右半侧查找

图解:

假设我们需要找5这个元素。

第一次查找:发现mid指向的值小于我们目的元素,letf就指向mid,right不移动,mid重新计算。



295a1dd09ebf43afa8a551b33dc8b244.png



第二次查找: 发现mid指向的值任然小于我们目的元素,letf就指向mid,right不移动,mid重新计算。


0b66170d4eb34027a54b8216a40a8f42.png

 

第三次查找:依旧和前两次查找一样。


69ea0b1f849d4a33a15c3a99829381bc.png


直到找到这个目标元素。

public class demo {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6};
        System.out.println(binarySearch(arr, 6));
    }
    public static int binarySearch(int[] arr, int toFind) {
        int left = 0;
        int right = arr.length - 1;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (toFind < arr[mid]) {
              // 去左侧区间找
                right = mid - 1;
            } else if (toFind > arr[mid]) {
                // 去右侧区间找
                left = mid + 1;
            } else {
                // 相等, 说明找到了
                return mid;
            }
        }
        // 循环结束, 说明没找到
        return -1;
        }
}

b08f2247246f4b889c0f619fff7425c2.png


这样三次就可以找到目标元素了。


3. 数组排序(冒泡排序)


给定一个数组, 让数组升序(降序) 排序。


算法思路


假设排升序:

1. 将数组中相邻元素从前往后依次进行比较,如果前一个元素比后一个元素大,则交换,一趟下来后最大元素 就在数组的末尾

2. 依次从上上述过程,直到数组中所有的元素都排列好


上代码:

import java.util.Arrays;
public class demo {
    public static void main(String[] args) {
        int[] arr = {9, 5, 2, 6, 8, 12, 7};
        bubbleSort(arr);
        System.out.println(Arrays.toString(arr));
    }
    public static void bubbleSort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 1; j < arr.length-i; j++) {
                if (arr[j-1] > arr[j]) {
                    int tmp = arr[j - 1];
                    arr[j - 1] = arr[j];
                    arr[j] = tmp;
                }
            }
        } // end for
    } // end bubbleSort
}

456b472982d44dc1a0239282c19a0310.png


当然了,冒泡排序是一种比较低效的的算法,我们Java提供了更高效的算法

public static void main(String[] args) {
        int[] arr = {9, 5, 2, 7};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
    }


7bf41a0d4c0143589cf6bc45d92dba7c.png


4. 转轮数组



ffacabd8e2bc439b920f772c79bdb5f6.png


最简单的解法:使用额外的数组

我们可以使用额外的数组来将每个元素放至正确的位置。用 nn 表示数组的长度,我们遍历原数组,将原数组下标为 ii 的元素放至新数组下标为 (i+k)\bmod n(i+k)modn 的位置,最后将新数组拷贝至原数组即可。

import java.util.Arrays;
public class demo {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7};
        rotate(arr,3);
        System.out.println(Arrays.toString(arr));
    }
    public static void rotate(int[] nums, int k) {
        int n = nums.length;
        int[] newArr = new int[n];
        for (int i = 0; i < n; ++i) {
            newArr[(i + k) % n] = nums[i];
        }
        System.arraycopy(newArr, 0, nums, 0, n);
    }
}

fdcc9e2643524262ae93734fe0f9e77e.png


也有其他的方法:数组翻转


思路:


三步翻转法,其实轮转数组类似于之前介绍过的倒置字符串,即整体先翻转,左半部分翻转,右半部分翻转,就能得到最终结果。假设数组 nums 为 1、2、3、4、5,轮转 3 次,先整体翻转(0 ~ numsSize - 1),数组为 5、4、3、2、1,再翻转左半部分(0 ~ k - 1),数组为 3、4、5、2、1,最后再翻转右半部分(k ~ numsSize - 1),数组为 3、4、5、1、2,结果出来了,这就是 三步翻转法 的奇妙解法


图示:


9ca050bb81a14537a17eaab59e604cc9.png


import java.util.Arrays;
public class demo {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7};
        rotate(arr,3);
        System.out.println(Arrays.toString(arr));
    }
    public static void rotate(int[] nums, int k) {
        k %= nums.length;
        reverse(nums, 0, nums.length - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, nums.length - 1);
    }
    public static void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start += 1;
            end -= 1;
        }
    }
}

5bf034a895f748bfa26548aee8f29a54.png

当然力扣官方还有一种解法:


10ca4b0579234a95b9046c9f3eab5838.png



我把链接放在这里:旋转数组 - 轮转数组 - 力扣(LeetCode) 感兴趣的可以去了解一下。

数组是个非常重要的点,以后刷题会经常用到数组,这里先介绍一些,后面遇到有趣的题目我还会在写进我的博客里。

相关文章
|
5月前
|
存储 缓存 Java
Java数组全解析:一维、多维与内存模型
本文深入解析Java数组的内存布局与操作技巧,涵盖一维及多维数组的声明、初始化、内存模型,以及数组常见陷阱和性能优化。通过图文结合的方式帮助开发者彻底理解数组本质,并提供Arrays工具类的实用方法与面试高频问题解析,助你掌握数组核心知识,避免常见错误。
|
7月前
|
自然语言处理 前端开发 Java
JBoltAI 框架完整实操案例 在 Java 生态中快速构建大模型应用全流程实战指南
本案例基于JBoltAI框架,展示如何快速构建Java生态中的大模型应用——智能客服系统。系统面向电商平台,具备自动回答常见问题、意图识别、多轮对话理解及复杂问题转接人工等功能。采用Spring Boot+JBoltAI架构,集成向量数据库与大模型(如文心一言或通义千问)。内容涵盖需求分析、环境搭建、代码实现(知识库管理、核心服务、REST API)、前端界面开发及部署测试全流程,助你高效掌握大模型应用开发。
751 5
|
7月前
|
前端开发 JavaScript Java
Java 学习路线规划及项目案例中的技术栈应用解析
内容包括:**Java 17核心特性**(如sealed class、record)与模块化开发;Spring Boot 3 + Spring Cloud微服务架构,涉及响应式编程(WebFlux)、多数据库持久化(JPA、R2DBC、MongoDB);云原生技术**如Docker、Kubernetes及CI/CD流程;性能优化(GraalVM Native Image、JVM调优);以及前后端分离开发(Vue 3、Spring Boot集成)。通过全栈电商平台项目实战,掌握从后端服务(用户、商品、订单)到前端应用(Vue 3、React Native)的全流程开发。
326 9
|
4月前
|
Java
Java 数组学习笔记
本文整理Java数组常用操作:遍历、求和、查找、最值及二维数组行求和等典型练习,涵盖静态初始化、元素翻倍、去极值求平均等实例,帮助掌握数组基础与应用。
|
7月前
|
人工智能 Java 开发者
【Java实例-简易计算机】使用Java实现简单的计算机案例
一个简单的Java案例——“简易计算器”,帮助编程新手快速上手。通过实现用户输入、基本逻辑运算和结果输出,学习者可以掌握变量声明、Scanner对象使用、控制流语句等关键知识点。文章分为设计思路、关键知识点、完整代码和测试运行四个部分。
234 9
【Java实例-简易计算机】使用Java实现简单的计算机案例
|
6月前
|
安全 Java API
Java 集合高级应用与实战技巧之高效运用方法及实战案例解析
本课程深入讲解Java集合的高级应用与实战技巧,涵盖Stream API、并行处理、Optional类、现代化Map操作、不可变集合、异步处理及高级排序等核心内容,结合丰富示例,助你掌握Java集合的高效运用,提升代码质量与开发效率。
300 0
|
6月前
|
安全 JavaScript Java
java Web 项目完整案例实操指南包含从搭建到部署的详细步骤及热门长尾关键词解析的实操指南
本项目为一个完整的JavaWeb应用案例,采用Spring Boot 3、Vue 3、MySQL、Redis等最新技术栈,涵盖前后端分离架构设计、RESTful API开发、JWT安全认证、Docker容器化部署等内容,适合掌握企业级Web项目全流程开发与部署。
535 0
|
6月前
|
存储 Java 索引
java 数组
在 Java 中,数组是一种数据结构,用于存储多个相同类型的数据元素。数组的大小一旦创建后就不能改变,因此它是固定长度的。Java 数组是一种 对象,即使它存储的值是基本类型(如 int、double 等),它也是一个对象引用。
177 0
|
7月前
|
缓存 算法 NoSQL
校招 Java 面试高频常见知识点深度解析与实战案例详细分享
《2025校招Java面试核心指南》总结了Java技术栈的最新考点,涵盖基础语法、并发编程和云原生技术三大维度: 现代Java特性:重点解析Java 17密封类、Record类型及响应式Stream API,通过电商案例演示函数式数据处理 并发革命:对比传统线程池与Java 21虚拟线程,详解Reactor模式在秒杀系统中的应用及背压机制 云原生实践:提供Spring Boot容器化部署方案,分析Spring WebFlux响应式编程和Redis Cluster缓存策略。
202 0