Create D lists of nodes where D is the depth of the binary tree I have used a HashMap of ArrayLists to maintain the nodes at each depth.
Also i maintained a depth at each node in the binary tree by using a HashMap that stores . While traversing the tree in a breadth first manner, store the depth of each node(just one more than the depth of its parent) in the hashmap and add the node to the queue. And add each element from the queue to the ArrayList corresponding to its depth in the binary tree.

import java.util.Collection;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.LinkedList;
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}
public class Solution {

    public List&lt;List&lt;Integer&gt;&gt; levelOrder(TreeNode root)
    {
        List&lt;List&lt;Integer&gt;&gt; outputList = new ArrayList&lt;List&lt;Integer&gt;&gt;();
        if(root == null)
        {
            return outputList;
        }
        Queue&lt;TreeNode&gt; queue =  new LinkedList&lt;TreeNode&gt;();
        HashMap&lt;Integer, ArrayList&lt;Integer&gt;&gt; haMap = new HashMap&lt;&gt;();
        HashMap&lt;TreeNode, Integer&gt; nodeDepth = new HashMap&lt;&gt;();
        nodeDepth.put(root,0);
        queue.add(root);
        ArrayList&lt;Integer&gt;  tempList;
        while(!queue.isEmpty())
        {
            root = (TreeNode) queue.poll();
            if(root.left != null)
            {
                nodeDepth.put(root.left, nodeDepth.get(root)+1);
                queue.add(root.left);
            }
            if(root.right != null)
            {
                nodeDepth.put(root.right, nodeDepth.get(root)+1);
                queue.add(root.right);
            }
            if(haMap.containsKey(nodeDepth.get(root)))
            {
                tempList = haMap.get(nodeDepth.get(root));
                tempList.add(root.val);
                haMap.put(nodeDepth.get(root), tempList);
            }
            else
            {
                tempList = new ArrayList&lt;&gt;();
                tempList.add(root.val);
                haMap.put(nodeDepth.get(root), tempList);
            }
        }

        //List&lt;List&lt;Integer&gt;&gt; outputList = new ArrayList&lt;List&lt;Integer&gt;&gt;();

        outputList.addAll(haMap.values());

        return outputList;

    }


}
Are TreeNode and Solution in separate files? If the shown code is a single file, then it will not compile as you cannot have 2 top-level classes in the same file in Java.
Edit: Turns out it's fine as long as there is only one top-level public class.
Otherwise, just a few minor issues that I can see.
Diamond Operators
You have used the diamond operator &lt;&gt; for haMap and nodeDepth, but you should also use it on outputList and queue.
For example, instead of initializing outputList like:
List&lt;List&lt;Integer&gt;&gt; outputList = new ArrayList&lt;List&lt;Integer&gt;&gt;();

you should initialize it like:
List&lt;List&lt;Integer&gt;&gt; outputList = new ArrayList&lt;&gt;();

and similarly for queue, just like how you did for haMap and nodeDepth.
Favor interfaces over classes
When you define your collections, you should use an interface instead of specifying a specific implementation. That way you can change the implementation easily.
For example, you have done this for outputList and queue, but you should also do it for haMap, nodeDepth, and tempList.
haMap should be defined as:
Map&lt;Integer, List&lt;Integer&gt;&gt; haMap = new HashMap&lt;&gt;();

and similarly for nodeDepth.
Variable Names
Some of your variable names are decent, such as nodeDepth and outputList. They tell me what the object is used for as opposed to what it is. However, queue and haMap could be better. What is queue a queue of? What is being stored in haMap?