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

编辑: admin 分类: java 发布时间: 2021-12-03 来源:互联网
目录
  • Java 递归遍历实现linux tree命令
    • 递归调用的函数traversal
    • printName函数
  • java实现zTree的遍历

    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。

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持自由互联。

    【转自:http://www.nextecloud.cn/jap.html 欢迎转载】