news 2026/4/23 11:11:42

冒泡排序,手写一个 java 数组排序。递归,Java实现文件夹遍历及文件打印。String类常用方法,读取字符串中第一行的方法。Java手写LinkedList实现指南。

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
冒泡排序,手写一个 java 数组排序。递归,Java实现文件夹遍历及文件打印。String类常用方法,读取字符串中第一行的方法。Java手写LinkedList实现指南。

冒泡排序,手写一个 java 数组排序

以下是一个手写 Java 数组排序的完整实现示例(使用冒泡排序算法),包含详细注释和测试代码:

publicclassManualArraySort{// 冒泡排序实现publicstaticvoidbubbleSort(int[]arr){intn=arr.length;// 外层循环控制排序轮数for(inti=0;i<n-1;i++){// 内层循环进行相邻元素比较for(intj=0;j<n-i-1;j++){// 如果前一个元素大于后一个元素,则交换位置if(arr[j]>arr[j+1]){// 元素交换操作inttemp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}}}publicstaticvoidmain(String[]args){int[]numbers={64,34,25,12,22,11,90};System.out.println("排序前数组:");printArray(numbers);// 打印原始数组bubbleSort(numbers);// 调用排序方法System.out.println("\n排序后数组:");printArray(numbers);// 打印排序结果}// 辅助方法:打印数组元素publicstaticvoidprintArray(int[]arr){for(intnum:arr){System.out.print(num+" ");}System.out.println();}}

代码说明:

  1. 排序算法:实现经典的冒泡排序算法,时间复杂度为O(n2)O(n^2)O(n2)
  2. 核心逻辑
    • 通过双重循环遍历数组
    • 比较相邻元素并进行交换
    • 每轮循环将最大元素"冒泡"到数组末尾
  3. 测试数据:使用示例数组{64, 34, 25, 12, 22, 11, 90}进行演示

输出结果:

排序前数组: 64 34 25 12 22 11 90 排序后数组: 11 12 22 25 34 64 90

其他排序算法选择:

若需更高效的实现,可考虑以下算法(时间复杂度对比):

  1. 快速排序:平均O(nlog⁡n)O(n \log n)O(nlogn)
  2. 归并排序:稳定O(nlog⁡n)O(n \log n)O(nlogn)
  3. 插入排序:对小数据集高效O(n2)O(n^2)O(n2)

提示:在实际开发中,推荐使用 Java 内置的Arrays.sort()方法(基于双轴快速排序实现),其性能经过高度优化

递归,Java实现文件夹遍历及文件打印

下面我将提供两种完整的Java实现方法,用于遍历文件夹并打印所有文件信息(包括子文件夹中的文件)。

方法一:递归遍历(深度优先)

importjava.io.File;publicclassFolderTraversal{publicstaticvoidmain(String[]args){// 指定要遍历的文件夹路径StringfolderPath="C:/example";// 替换为你的文件夹路径Filefolder=newFile(folderPath);// 检查文件夹是否存在if(!folder.exists()||!folder.isDirectory()){System.out.println("指定的路径不是一个有效的文件夹!");return;}System.out.println("开始遍历文件夹: "+folderPath);traverseFolderRecursive(folder);}/** * 递归遍历文件夹并打印所有文件 * @param folder 要遍历的文件夹 */publicstaticvoidtraverseFolderRecursive(Filefolder){// 获取文件夹下的所有文件和子文件夹File[]files=folder.listFiles();// 检查文件夹是否为空if(files==null){return;}// 遍历所有文件和子文件夹for(Filefile:files){if(file.isFile()){// 打印文件信息System.out.println("文件: "+file.getAbsolutePath()+" | 大小: "+file.length()+" bytes");}elseif(file.isDirectory()){// 跳过特殊目录 "." 和 ".."if(!".".equals(file.getName())&&!"..".equals(file.getName())){// 递归遍历子文件夹traverseFolderRecursive(file);}}}}}

方法二:队列实现(广度优先)

importjava.io.File;importjava.util.LinkedList;importjava.util.Queue;publicclassFolderTraversalBFS{publicstaticvoidmain(String[]args){// 指定要遍历的文件夹路径StringfolderPath="C:/example";// 替换为你的文件夹路径FilerootFolder=newFile(folderPath);// 检查文件夹是否存在if(!rootFolder.exists()||!rootFolder.isDirectory()){System.out.println("指定的路径不是一个有效的文件夹!");return;}System.out.println("开始遍历文件夹: "+folderPath);traverseFolderWithQueue(rootFolder);}/** * 使用队列实现文件夹遍历(广度优先) * @param rootFolder 根文件夹 */publicstaticvoidtraverseFolderWithQueue(FilerootFolder){// 创建队列用于存储待遍历的文件夹Queue<File>folderQueue=newLinkedList<>();folderQueue.add(rootFolder);// 遍历队列中的所有文件夹while(!folderQueue.isEmpty()){FilecurrentFolder=folderQueue.poll();// 获取当前文件夹下的所有文件和子文件夹File[]files=currentFolder.listFiles();if(files==null){continue;}// 遍历所有文件和子文件夹for(Filefile:files){if(file.isFile()){// 打印文件信息System.out.println("文件: "+file.getAbsolutePath()+" | 大小: "+file.length()+" bytes");}elseif(file.isDirectory()){// 跳过特殊目录 "." 和 ".."if(!".".equals(file.getName())&&!"..".equals(file.getName())){// 将子文件夹加入队列folderQueue.add(file);}}}}}}

使用说明

  1. 替换路径:将代码中的C:/example替换为你要遍历的实际文件夹路径
  2. 两种遍历方式
    • 递归实现:深度优先遍历,简单直观
    • 队列实现:广度优先遍历,避免深层递归可能导致的栈溢出
  3. 输出信息:程序会打印每个文件的完整路径和文件大小
  4. 特殊目录处理:自动跳过.(当前目录)和..(上级目录)特殊目录

扩展功能示例:只打印特定类型的文件

// 在遍历文件时添加文件类型检查if(file.isFile()){StringfileName=file.getName();// 只打印图片文件(扩展名检查)if(fileName.toLowerCase().endsWith(".jpg")||fileName.toLowerCase().endsWith(".png")){System.out.println("图片文件: "+file.getAbsolutePath()+" | 大小: "+file.length()+" bytes");}}

注意事项

  1. 权限问题:程序需要具有访问指定文件夹的权限
  2. 大文件夹处理:对于包含大量文件的文件夹,递归方法可能导致栈溢出,建议使用队列实现
  3. 特殊符号:路径中包含中文或特殊符号时,确保使用正确的字符编码

这些方法可以帮助你高效地遍历文件夹并处理文件。实际应用中,你可以根据需要修改文件处理逻辑,例如统计文件数量、搜索特定文件或处理文件内容。

String类常用方法,Java 读取字符串中第一行的方法

在 Java 中,读取多行字符串的第一行数据有多种实现方法。以下是几种高效可靠的解决方案:

方法一:使用indexOf()substring()(推荐)

publicclassReadFirstLine{publicstaticStringgetFirstLine(Stringinput){if(input==null||input.isEmpty()){returninput;}// 查找第一个换行符位置(支持 \n 和 \r\n)intnewlineIndex=indexOfNewline(input);return(newlineIndex!=-1)?input.substring(0,newlineIndex):input;}privatestaticintindexOfNewline(Stringstr){for(inti=0;i<str.length();i++){charc=str.charAt(i);if(c=='\n'){returni;// 找到 \n}elseif(c=='\r'){// 检查是否是 \r\nif(i+1<str.length()&&str.charAt(i+1)=='\n'){returni;// 返回 \r 的位置}returni;// 单独的 \r}}return-1;// 没有换行符}publicstaticvoidmain(String[]args){Stringtext="第一行内容\n第二行内容\n第三行内容";StringfirstLine=getFirstLine(text);System.out.println("第一行: "+firstLine);}}

方法二:使用split()方法

publicstaticStringgetFirstLineWithSplit(Stringinput){if(input==null)returnnull;// 使用正则表达式分割字符串(支持多种换行符)String[]lines=input.split("\\r?\\n|\\r",2);returnlines[0];// 返回分割后的第一段}

方法三:使用BufferedReader

publicstaticStringgetFirstLineWithReader(Stringinput){if(input==null)returnnull;try(BufferedReaderreader=newBufferedReader(newStringReader(input))){returnreader.readLine();// 读取第一行(自动处理换行符)}catch(IOExceptione){// StringReader 不会抛出 IOException,此处仅用于语法完整性returninput;}}

性能比较与推荐

方法优点缺点适用场景
indexOf()+substring()高效,不创建额外对象需要手动处理换行符性能敏感场景
split()代码简洁效率较低,创建字符串数组简单场景
BufferedReader自动处理换行符需要异常处理,创建额外对象需要兼容多种换行符

推荐使用第一种方法indexOf()+substring()),因为它:

  1. 效率最高,不创建额外对象
  2. 明确处理了各种换行符情况(\n\r\r\n
  3. 避免正则表达式或流处理的额外开销

使用示例

publicstaticvoidmain(String[]args){// 测试不同换行符场景String[]testCases={"单行文本","第一行\n第二行","第一行\r第二行","第一行\r\n第二行","\n以换行符开头",""// 空字符串};for(Stringtext:testCases){System.out.println("原始文本: \""+text+"\"");System.out.println("第一行: \""+getFirstLine(text)+"\"");System.out.println("--------------------");}}

处理特殊情况的建议

  1. 空字符串或 null:方法中已包含空值检查
  2. 无换行符:返回整个字符串
  3. 特殊换行符:支持\n(Unix/Linux)、\r(旧版 Mac)、\r\n(Windows)
  4. 大字符串处理:推荐使用第一种方法避免创建额外对象

提示:如果只需要判断字符串是否包含多行内容,可以使用contains()方法检查换行符:

booleanisMultiline=input.contains("\n")||input.contains("\r");

Java手写LinkedList实现指南

我将详细解释如何手写一个双向链表(LinkedList)的实现,参考了Java官方LinkedList的设计原理。

双向链表核心实现

1. 节点类(Node)

privatestaticclassNode<E>{Eitem;// 存储的数据Node<E>prev;// 前驱节点Node<E>next;// 后继节点// 节点构造函数Node(Node<E>prev,Eelement,Node<E>next){this.item=element;this.prev=prev;this.next=next;}}

2. LinkedList类框架

publicclassLinkedList<E>{privateNode<E>first;// 头节点privateNode<E>last;// 尾节点privateintsize=0;// 链表大小// 构造函数publicLinkedList(){}// 基本操作方法将在下面实现}

核心方法实现

1. 添加元素方法

// 在链表尾部添加元素publicvoidadd(Ee){addLast(e);}// 在链表尾部添加元素publicvoidaddLast(Ee){finalNode<E>l=last;finalNode<E>newNode=newNode<>(l,e,null);last=newNode;if(l==null){first=newNode;// 链表为空时}else{l.next=newNode;// 连接新节点}size++;}// 在链表头部添加元素publicvoidaddFirst(Ee){finalNode<E>f=first;finalNode<E>newNode=newNode<>(null,e,f);first=newNode;if(f==null){last=newNode;// 链表为空时}else{f.prev=newNode;// 连接新节点}size++;}// 在指定索引处插入元素publicvoidadd(intindex,Eelement){checkPositionIndex(index);// 检查索引是否有效if(index==size){addLast(element);}else{Node<E>succ=node(index);Node<E>pred=succ.prev;Node<E>newNode=newNode<>(pred,element,succ);succ.prev=newNode;if(pred==null){first=newNode;}else{pred.next=newNode;}size++;}}

2. 获取元素方法

// 获取指定索引处的元素publicEget(intindex){checkElementIndex(index);// 检查索引是否有效returnnode(index).item;}// 获取第一个元素publicEgetFirst(){if(first==null)thrownewNoSuchElementException();returnfirst.item;}// 获取最后一个元素publicEgetLast(){if(last==null)thrownewNoSuchElementException();returnlast.item;}// 查找指定索引处的节点Node<E>node(intindex){// 根据位置选择从头或尾开始遍历if(index<(size>>1)){Node<E>x=first;for(inti=0;i<index;i++)x=x.next;returnx;}else{Node<E>x=last;for(inti=size-1;i>index;i--)x=x.prev;returnx;}}

3. 删除元素方法

// 删除指定索引处的元素publicEremove(intindex){checkElementIndex(index);returnunlink(node(index));}// 删除指定节点Eunlink(Node<E>x){finalEelement=x.item;finalNode<E>next=x.next;finalNode<E>prev=x.prev;// 处理前驱节点if(prev==null){first=next;}else{prev.next=next;x.prev=null;// 断开连接}// 处理后继节点if(next==null){last=prev;}else{next.prev=prev;x.next=null;// 断开连接}x.item=null;// 帮助垃圾回收size--;returnelement;}

4. 辅助方法

// 检查元素索引是否有效privatevoidcheckElementIndex(intindex){if(index<0||index>=size)thrownewIndexOutOfBoundsException(outOfBoundsMsg(index));}// 检查位置索引是否有效privatevoidcheckPositionIndex(intindex){if(index<0||index>size)thrownewIndexOutOfBoundsException(outOfBoundsMsg(index));}// 创建越界错误信息privateStringoutOfBoundsMsg(intindex){return"Index: "+index+", Size: "+size;}// 返回链表大小publicintsize(){returnsize;}// 判断链表是否为空publicbooleanisEmpty(){returnsize==0;}

性能分析

操作时间复杂度说明
头部插入O(1)O(1)O(1)直接修改头节点引用
尾部插入O(1)O(1)O(1)直接修改尾节点引用
中间插入O(n)O(n)O(n)需要遍历到指定位置
头部删除O(1)O(1)O(1)直接修改头节点引用
尾部删除O(1)O(1)O(1)直接修改尾节点引用
中间删除O(n)O(n)O(n)需要遍历到指定位置
随机访问O(n)O(n)O(n)需要遍历链表
顺序访问O(1)O(1)O(1)通过节点指针直接访问下一个元素

使用示例

publicclassMain{publicstaticvoidmain(String[]args){LinkedList<String>list=newLinkedList<>();// 添加元素list.add("Apple");list.addFirst("Banana");list.addLast("Orange");list.add(1,"Grape");// 遍历链表for(inti=0;i<list.size();i++){System.out.println("Index "+i+": "+list.get(i));}// 删除元素list.remove(0);System.out.println("First element after removal: "+list.getFirst());}}

链表与数组性能对比

  1. 插入/删除效率

    • 链表:已知位置时O(1)O(1)O(1),查找位置时O(n)O(n)O(n)
    • 数组:随机插入/删除需要移动元素O(n)O(n)O(n)
  2. 内存使用

    • 链表:每个元素需要额外空间存储前后指针
    • 数组:连续内存空间,无额外指针开销
  3. 访问效率

    • 链表:随机访问O(n)O(n)O(n)
    • 数组:随机访问O(1)O(1)O(1)

相关问题

  1. 如何实现循环双向链表?
  2. 链表反转的最佳实现方式是什么?
  3. 如何检测链表中的环?
  4. 链表排序有哪些高效算法?
  5. 如何实现线程安全的链表?
  6. 链表和数组在内存管理上有何不同?

通过手写LinkedList实现,可以深入理解链表的操作原理和性能特点,为后续学习更复杂的数据结构打下基础。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 11:11:29

AI Agent在智能枕头中的颈椎保护系统

AI Agent在智能枕头中的颈椎保护系统关键词&#xff1a;AI Agent、智能枕头、颈椎保护系统、传感器技术、机器学习算法摘要&#xff1a;本文深入探讨了AI Agent在智能枕头颈椎保护系统中的应用。首先介绍了该研究的背景&#xff0c;包括目的、预期读者、文档结构和相关术语。接…

作者头像 李华
网站建设 2026/4/23 12:38:50

5步实现企业级LLM平台自动化部署:GitHub Actions深度实战

还在为频繁的Bisheng版本发布而头疼&#xff1f;面对多架构支持、私有仓库同步、版本控制等复杂环节&#xff0c;手动部署不仅效率低下&#xff0c;还容易引入人为错误。本文将带你深入GitHub Actions的自动化部署世界&#xff0c;从零构建一套完整的企业级LLM平台CI/CD流水线。…

作者头像 李华
网站建设 2026/4/23 11:12:54

BrowserBee:用自然语言智能操控浏览器的革命性助手

BrowserBee&#xff1a;用自然语言智能操控浏览器的革命性助手 【免费下载链接】browserbee &#x1f41d; AI-powered browser assistant ("Cline for web browsing") 项目地址: https://gitcode.com/gh_mirrors/br/browserbee 在当今信息爆炸的时代&#xf…

作者头像 李华
网站建设 2026/4/23 13:46:49

阿里Qwen3-Omni-Flash发布:实时全模态交互,API定价1元起

2025年12月09日&#xff0c;阿里巴巴Qwen团队带来了一则重磅消息——正式发布新一代全模态大模型Qwen3-Omni-Flash-2025-12-01。这一模型的诞生&#xff0c;无疑为全模态交互领域注入了新的活力&#xff0c;引发了行业内外的广泛关注。 实时流式架构&#xff1a;打破模态壁垒&a…

作者头像 李华
网站建设 2026/4/23 17:06:27

终极指南:如何为Nintendo Switch制作个性化hekate开机画面

你是否厌倦了Switch开机时千篇一律的默认画面&#xff1f;想要让爱机从启动瞬间就与众不同&#xff1f;hekate作为Nintendo Switch最受欢迎的GUI引导程序&#xff0c;为你提供了完整的bootlogo定制方案。本指南将通过5个简单步骤&#xff0c;带你从零开始打造专属开机画面&…

作者头像 李华
网站建设 2026/4/23 14:27:26

Apache Druid监控终极指南:从零构建生产级监控告警体系

你是否曾经遇到过这样的场景&#xff1a;Druid集群在凌晨突然出现性能瓶颈&#xff0c;查询响应时间从毫秒级飙升到秒级&#xff0c;而你却束手无策&#xff1f;或者当数据摄入任务失败时&#xff0c;只能通过查看日志来排查问题&#xff0c;错失了最佳的恢复时机&#xff1f;&…

作者头像 李华