Skip to content
Advertisement

Finding a the “sub-path” in a hierarchical system, Java

I have this Hierarchical file system that is built like so:

class StorageUnit{
    String name;
    StorageUnit(String nameInput){
        this.name = nameInput;
    }
}

class Folder extends StorageUnit{
    ArrayList<StorageUnit> items = new ArrayList<StorageUnit>();
    
    void addContent(StorageUnit item){
         this.items.add(item);
    }
}

class File extends StorageUnit{}

Given a path (not necessarily the complete path) for example for this system:

A
|    B
|    |    C
|    |    |    code.java
|    |    bye.log
|    Aa.txt
|    aa.py

a path be given like so:

B/C/code.java

I am trying to make a function return the specified File if there exists a path where the given path is part of it, for example if it finds the path:

A/B/C/code.java

the function would return code.java since the found path contains the given path, else it returns null.

I thought about recursion, however, can’t figure out what to do it if I end up in a file that doesn’t contain the file am looking for:

//The entire code here belongs to the class StorageUnit

public File findFile(String path){
        String[] paths = path.split("/");

        return findFile_aux(paths,0);
    }
public File findFile_aux(String[] paths, int i){
        for(StorageItem item : this.items){
            if(item.getName().equals(paths[i])){
                if(i == paths.length-1) {
                    return ((File) item);
                }
                item.findFile_aux(paths, i+1);
            }
            item.findFile_aux(paths, i);
        }
        return null;
    }

Advertisement

Answer

  1. You missed to return your recursive call
  2. You have to give the current folder to the recursive call, otherwise you allways look at A‘s items.
  3. You get a ClassCastException if your path leads to a folder
private static File find(Folder root, String path) {
    return find(path.split("/"), Collections.singletonList(root), 0);
}

private static File find(String[] path, List<StorageUnit> units, int depth) {
    if (depth >= path.length) {
        // file not found
        return null;
    }
    String currentStep = path[depth];
    for (StorageUnit unit : units) {
        if (currentStep.equals(unit.name)) {
            // step found
            if (depth == path.length - 1) {
                // last step -> unit found
                if (unit instanceof File) {
                    return (File) unit;
                } else {
                    // path doesn't lead to a file (point 3)
                    System.err.println("path doesn't leed to a file but " + unit);
                    return null;
                }
            } else if (unit instanceof Folder) {
                // next step
                Folder folder = (Folder) unit;
                // recursive call with items of current folder (point 2)
                File file = find(path, folder.items, depth + 1);
                if (file != null) {
                    // found it (point 1)
                    return file;
                }
                // else -> not found -> ignore unit
            }
        }
    }
    return null;
}
Advertisement