In-Memory FileSystem in Java - Is there a better OOP approach? I have implemented an in-memory filesystem - this is a design question from LeetCode. Is there a better OOP approach to represent files and directories? The current code uses a boolean flag isDirectory to distinguish between files and directories and I'm not confident that it is the best approach. See the code below. I'll also be happy to get any other comments about the code - readability, variable and method naming, etc.
class FileSystem {
    
    Inode root;

    public FileSystem() 
    {
        root = new Inode(&quot;/&quot;, true);
    }
    
    public List&lt;String&gt; ls(String path) 
    {
        List&lt;String&gt; listing = new ArrayList&lt;&gt;();
        
        String[] queries = path.substring(1).split(&quot;/&quot;);
        
        Inode node = root;
        
        for(String query: queries)
        {
            if(query.isEmpty()) // happens when we search root
                break;
            
            node = node.children.get(query);
            
            if(node == null)
                return listing;
        }
        
        if(node.isDirectory)
        {
            node.children.forEach((name, inode) -&gt; { 
                listing.add(name);
            });
        }
        else
        {
            listing.add(node.Name);
        }
        
           
        Collections.sort(listing);
        
        return listing;
    }
    
    public void mkdir(String path) 
    {
        String[] subdirs = path.substring(1).split(&quot;/&quot;);
        Inode node = root;
        
        for(String dir: subdirs)
        {
            if(dir.isEmpty()) // happens when we search root
                break;
            
            if(!node.children.containsKey(dir))
                node.children.put(dir, new Inode(dir, true));
            
            node = node.children.get(dir);
        }
        
    }
    
    public void addContentToFile(String filePath, String content) 
    {
        String[] subdirs = filePath.substring(1).split(&quot;/&quot;);
        Inode node = root;
        
        for(int i=0; i&lt;subdirs.length; i++)
        {
            if(!node.children.containsKey(subdirs[i]))
            {
                if(i &lt; subdirs.length-1)
                    node.children.put(subdirs[i], new Inode(subdirs[i], true));
                else
                    node.children.put(subdirs[i], new Inode(subdirs[i], false));
                
            }
                
            node = node.children.get(subdirs[i]);
        }
        
        node.fileContent.append(content);
        
    }
    
    public String readContentFromFile(String filePath) 
    {
        String[] subdirs = filePath.substring(1).split(&quot;/&quot;);
        Inode node = root;
        
        for(String dir: subdirs)
        {
            node = node.children.get(dir);
        }
        
        return node.fileContent.toString();
    }
    
}

// Trie data structure for files and directories

    class Inode
    {
        public String Name;
        public boolean isDirectory=true;
        public StringBuilder fileContent=null;
        public HashMap&lt;String, Inode&gt; children = null;
        
        public Inode(String name, boolean is_dir)
        {
            this.Name = name;
            this.isDirectory = is_dir;
            
            if(!is_dir)
                fileContent = new StringBuilder();
            
            if(is_dir &amp;&amp; children == null)
                children = new HashMap&lt;&gt;();
        }
        
    }
create Subclasses / interfaces
if you think there is a difference in Behaviour then there is a need for a seperate class - if you think some classes have something in common, extract an interface!
so create a class Directory and a class File. Let both classes implement the Node Interface. (Note - in Java we don't use the hungarian notation )
inconsistency // oo-abuse
what's the purpose of Node if you don't use it? compare these two approaches

public List&lt;String&gt; ls(String path) vs.
public List&lt;Node&gt; ls(Node path)

in case 1 it is absolutly not clear how the String path should look like, especially since it is OS-dependant. (what would String[] subdirs = filePath.substring(1).split(&quot;/&quot;); on other OS do?) It is also not clear what kind of output this Method delivers
in case 2 we have cleary declared what kind of input we expect, (even though i'm missing a parent attribut - that would ease up the searching) - we reduce the problem with different OSes to the single place where it belongs: at the constructor of the Node (Single responsibility). And we have a very accurate output (compared to the List&lt;String&gt; from case 1 - how would we know if a String is a Directory or a File? Node already provides all these information!)
File System vs. Editor
i'm not sure how addContentToFile() and readContentFromFile match for a FileSystem - in my opinion these two methods belong to an Editor/Viewer and not the the File System - create an Editor (an Editor class)!
think of the possibilities: you can then provide different Editors for different file Types?
Error Handling
i would expect a file system to be a bit more chatty about IllegalArgumentException (why are none thrown? how is such case treated?)