Java 递归遍历实现linux tree命令方式

 更新时间:2021年09月18日 09:45:10   作者:bsbhenry  
这篇文章主要介绍了Java 递归遍历实现linux tree命令方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Java 递归遍历实现linux tree命令

看到介绍java file类的文章,有一个遍历文件夹的练习,遍历某个目录下所有文件,包括子目录。写了一个用栈实现的递归遍历。

import java.io.File;
import java.util.Stack;
public class TraversalFile {
	
	public static void main(String[] args) {
		File dir = new File("D:/Study/code/Java/TraversalFile");
		traversal(dir,1);
	}
 
	public TraversalFile() {
		// TODO Auto-generated constructor stub
	}
	
	public static void traversal(File file,int depth) {
		printName(file, depth);
		File[] fileArray = file.listFiles();
		
		Stack<File> stack = new Stack<File>();
		for(File f:fileArray) {
			if(f.isFile()) {
				printName(f, depth + 1);				
			}
			else {
				stack.add(f);
			}
		}
		
		while(stack.isEmpty() == false) {
			traversal(stack.pop(),depth + 1);
		}
	}
	
	public static void printName(File f, int signNum) {
		StringBuilder builder = new StringBuilder();
		//signNum个sign
		
		for(int i=0;i<signNum;i++){		   
		   if(i == signNum - 1)
			   builder.append("|--"); 
		   else
			   builder.append("  ");
		}
		
		String str = builder.toString();
		System.out.println(str + f.getName());
	}
}

效果如下

递归调用的函数traversal

	public static void traversal(File file,int depth) {
		printName(file, depth);
		File[] fileArray = file.listFiles();
		
		Stack<File> stack = new Stack<File>();
		for(File f:fileArray) {
			if(f.isFile()) {
				printName(f, depth + 1);				
			}
			else {
				stack.add(f);
			}
		}
		
		while(stack.isEmpty() == false) {
			traversal(stack.pop(),depth + 1);
		}
	}

函数首先调用了一个printName函数,用来打印当前传入文件的名字,包括前面的线条,然后遍历当前文件的子文件,如果是文件类型就打印出来,但是深度+1,深度是用来通过打印字符显示出文件层次的,如果是目录就入栈。遍历结束后就出栈并递归调用 traversal,直到所有文件打印完毕。

不使用stack也可以实现遍历,但是fileArray里面可能文件和目录是混着的,显示出来会比较乱,如果先打印文件,目录都入栈,之后处理,就可以区别开。

如果不考虑文件和目录是混着输出,下面这种写法更简洁。

如果是文件就返回,是目录就递归调用。

	public static void traversal(File file,int depth) {
		printName(file, depth);		
		if (file.isFile())
			return;		
		File[] fileArray = file.listFiles();
		for(File f:fileArray) {
			traversal(f, depth + 1);
		}
	}

结果如下

printName函数

	public static void printName(File f, int signNum) {
		StringBuilder builder = new StringBuilder();
		//signNum个sign
		
		for(int i=0;i<signNum;i++){		   
		   if(i == signNum - 1)
			   builder.append("|--"); 
		   else
			   builder.append("  ");
		}
		
		String str = builder.toString();
		System.out.println(str + f.getName());
	}

文件或目录名前根据层级填充空格,最后用 |--紧接名字。

java实现zTree的遍历

entity代码:

public class CategoryVO {
	private Integer id;
	private Integer pId;
	private String name;
	private String url;
	private List<CategoryVO> children=new ArrayList<CategoryVO>();
	//get set 省略
}

数据是这样的:

在这里插入图片描述

实现代码:

public List<CategoryVO> list(String name,Model model){
		List<CategoryVO> categoryList = CategoryJDBC.getCategoryList();
		
		HashMap<Integer, CategoryVO> tmpMap = new HashMap<>(); // 所有对象存放到map中
		for (CategoryVO categoryVO : categoryList) {
			tmpMap.put(categoryVO.getId(), categoryVO);
		}
		
		ArrayList<CategoryVO> arrayList = new ArrayList<>(); // 结果list,之所以用list,是考虑到有多个根目录的情况
		for (CategoryVO categoryVO : categoryList) {  // 遍历所有元素,放到对应的父节点
			if(tmpMap.get(categoryVO.getpId())!=null && categoryVO.getId()!=categoryVO.getpId() ){
				CategoryVO categoryVO2 = tmpMap.get(categoryVO.getpId()); //map中找到父节点
				List<CategoryVO> children = categoryVO2.getChildren(); 
				children.add(categoryVO); // 添加到父节点的children里
				categoryVO2.setChildren(children); 
				tmpMap.put(categoryVO2.getId(), categoryVO2); //重置添加children后的map
				
			}else{
				arrayList.add(categoryVO);
			}
		}
		return categoryList;
	}

该方法只用了2次遍历。

第一次,遍历所有对象,放到tmpMap中。

第二次,遍历所有对象,通过tmpMap找到每个节点对应的父节点,并添加到父节点children中。然后父节点再放回map。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java数据存储的“双子星”对决(Map和Set的区别)

    Java数据存储的“双子星”对决(Map和Set的区别)

    文章主要介绍了Java中Map和Set两种数据结构的定义、实现、方法及应用场景,Map用于存储键值对,键唯一,值可重复;Set用于存储唯一元素,无序,两者都提供了丰富的操作方法,如添加、删除、查找等,感兴趣的朋友一起看看吧
    2025-02-02
  • spring security 自定义Provider 如何实现多种认证

    spring security 自定义Provider 如何实现多种认证

    这篇文章主要介绍了spring security 自定义Provider实现多种认证方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • 关于request.getRequestDispatcher().forward()的妙用及DispatcherType对Filter配置的影响

    关于request.getRequestDispatcher().forward()的妙用及DispatcherType

    这篇文章主要介绍了关于request.getRequestDispatcher().forward()的妙用及DispatcherType对Filter配置的影响,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Java调用浏览器打开网页完整实例

    Java调用浏览器打开网页完整实例

    这篇文章主要介绍了Java调用浏览器打开网页的方法,以完整实例形式分析了java打开网页的相关技巧,需要的朋友可以参考下
    2015-05-05
  • 基于常用json框架介绍和Jackson返回结果处理方式

    基于常用json框架介绍和Jackson返回结果处理方式

    这篇文章主要介绍了基于常用json框架介绍和Jackson返回结果处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Java中过滤器、监听器和拦截器的区别详解

    Java中过滤器、监听器和拦截器的区别详解

    这篇文章主要介绍了Java中过滤器、监听器和拦截器的区别详解,有些朋友可能不了解过滤器、监听器和拦截器的区别,本文就来详细讲一下,相信看完你会有所收获,需要的朋友可以参考下
    2024-01-01
  • IDEA2020.3创建web工程的完整步骤

    IDEA2020.3创建web工程的完整步骤

    这篇文章主要给大家介绍了关于IDEA2020.3创建web工程的完整步骤,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Java线程池中的Future实现详解

    Java线程池中的Future实现详解

    这篇文章主要介绍了Java线程池中的Future实现详解, FutureTask是一个任务,FutureTask继承了Runnable、Callable, 通过FutureTask可以获取到任务执行的状态,任务执行完成完成后,将结构通过Future接口返回,调用者可以调用Future#get()方法获取到数据,需要的朋友可以参考下
    2023-10-10
  • Docker 快速部署Springboot项目超详细最新版

    Docker 快速部署Springboot项目超详细最新版

    这篇文章主要介绍了Docker 快速部署Springboot项目超详细最新版的相关资料,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • Java实现贪吃蛇游戏源码

    Java实现贪吃蛇游戏源码

    这篇文章主要为大家详细介绍了Java实现贪吃蛇游戏源码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11

最新评论