-1

I want to implement the following code. The requirements are as follow

  1. Complete the constructor and test what you did in method main.
  2. In method main, build a tree with a few nodes, then call findChild for each of the names. They will fail. Complete method findChild until the tests pass.

One thing I'm confused is that the FileNode for f1 is null, and null value cannot be put in hashmap (will show the null pointer error). How should I do to prevent this issue.

Here is the code I did

package part2;

import java.util.Map;

import javax.swing.JFileChooser;

import java.io.File;
import java.util.Collection;


/**
 * The root of a tree representing a directory structure.
 */
public class FileNode {

    /** The name of the file or directory this node represents. */
    private String name;
    /** Whether this node represents a file or a directory. */
    private FileType type;
    /** This node's parent. */
    private FileNode parent;
    /**
     * This node's children, mapped from the file names to the nodes. If type is
     * FileType.FILE, this is null.
     */
    private Map<String, FileNode> children;

    /**
     * A node in this tree.
     *
     * @param name
     *            the file
     * @param parent
     *            the parent node.
     * @param type
     *            file or directory
     * @see buildFileTree
     */
    public FileNode(String name, FileNode parent, FileType type) {
        this.name = name;
        this.parent = parent;
        this.type = type;



        // TODO: complete this method.
    }

    /**
     * Find and return a child node named name in this directory tree, or null
     * if there is no such child node.
     *
     * @param name
     *            the file name to search for
     * @return the node named name
     */
    public FileNode findChild(String name) {
        // TODO: complete this method.
            if (children.containsKey(name)) {
                return children.get(name);
            } 
            else{
                return null;
            }

    }

    /**
     * Return the name of the file or directory represented by this node.
     *
     * @return name of this Node
     */
    public String getName() {
        return this.name;
    }

    /**
     * Set the name of the current node
     *
     * @param name
     *            of the file/directory
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Return the child nodes of this node.
     *
     * @return the child nodes directly underneath this node.
     */
    public Collection<FileNode> getChildren() {
        return this.children.values();
    }

    /**
     * Return this node's parent.
     * 
     * @return the parent
     */
    public FileNode getParent() {
        return parent;
    }

    /**
     * Set this node's parent to p.
     * 
     * @param p
     *            the parent to set
     */
    public void setParent(FileNode p) {
        this.parent = p;
    }

    /**
     * Add childNode, representing a file or directory named name, as a child of
     * this node.
     * 
     * @param name
     *            the name of the file or directory
     * @param childNode
     *            the node to add as a child
     */
    public void addChild(String name, FileNode childNode) {
        this.children.put(name, childNode);
    }

    /**
     * Return whether this node represents a directory.
     * 
     * @return whether this node represents a directory.
     */
    public boolean isDirectory() {
        return this.type == FileType.DIRECTORY;
    }

    /**
     * This method is for code that tests this class.
     * 
     * @param args
     *            the command line args.
     */
    public static void main(String[] args) {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        int returnVal = fileChooser.showOpenDialog(null);
        File file;

        if (returnVal == JFileChooser.APPROVE_OPTION) {
            file = fileChooser.getSelectedFile();
            System.out.println(file);
        }
        System.out.println("Testing FileNode");
        FileNode f1 = new FileNode("top", null, FileType.FILE);
        FileNode f2 = new FileNode("top", f1, FileType.FILE);

        f2 = file;
        f1.addChild("c1", f2);

        System.out.println(f2.findChild("c1"));
        if (!f1.getName().equals("top")) {
            System.out.println("Error: " + f1.getName() + " should be " + "top");
        }


    }

}

and here is the error message:

Exception in thread "main" java.lang.NullPointerException
    at part2.FileNode.addChild(FileNode.java:126)
    at part2.FileNode.main(FileNode.java:152)
Phantômaxx
  • 36,442
  • 21
  • 78
  • 108
J.DOE
  • 11
  • 6
  • Where do you need to put null into the HashMap? `this.name = name; this.parent = parent;` What is the problem with that? – OneCricketeer Oct 13 '16 at 02:58
  • Interpret a null parent as "No parent, thus is has to be in the root directory" so you search for a file system entry of "/" – Adrian Colomitchi Oct 13 '16 at 02:58
  • Since you seem to have `TODO` without some attempt. [An open letter to students with homework problems](http://meta.programmers.stackexchange.com/questions/6166/open-letter-to-students-with-homework-problems) – OneCricketeer Oct 13 '16 at 03:01
  • @AdrianColomitchi, yes I know, but how to convert the file to FileNode. The FileNode should be a file – J.DOE Oct 13 '16 at 03:02
  • @cricket_007, I did. but my code didn't work. Should I update my code? – J.DOE Oct 13 '16 at 03:04
  • 1
    Possible duplicate of [What is a NullPointerException, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Phantômaxx Oct 13 '16 at 08:26

1 Answers1

0

the FileNode for f1 is null, and null value cannot be put in hashmap

I think null can be put in HashMap, at least as the value.

The error means that children == null, because you never initialized it! So fix that...

public void addChild(String name, FileNode childNode) {
    if (this.children == null) {
        this.children = new HashMap<String, FileNode>();
    }
    this.children.put(name, childNode);
}

When you find a child, though, you are only checking the immediate children. You need to iterate down the file-tree until you find what you want.

public FileNode findChild(String name) {
    // Base case - no children
    if (children == null) return null;

    // Get the child, if exists
    FileNode immediateChild = children.get(name);
    if (immediateChild != null) {
        return children.get(name);
    } 
    else { // Iterate all children until found
        FileNode tmp = null;
        for (FileNode f : getChildren()) {
            if (tmp != null) break;
            tmp = f.getChild(name);
        }
        return tmp;
    }
}
OneCricketeer
  • 126,858
  • 14
  • 92
  • 185