Is there a way to retrieve all the leaf nodes of a Java TreeMap
?
I have a TreeMap
like this
TreeMap<String, FooBar> myTree = new TreeMap<String, FooBar>(new Comparator<String>() {
public int compare(String o1, String o2)
{
int b1 = Integer.parseInt(o1, 2);
int b2 = Integer.parseInt(o2, 2);
return (b1 > b2 ? 1 : (b1 == b2 ? 0 : -2));
}
});
How do I get all the leaf nodes of this tree?
This doesn't make much sense to me. The elements stored at the leaves are dependent on how the implementation of TreeMap balances the tree.
But, let's say you needed to do this for some reason. To actually do this, you would need to do a bit of a hack: write a class packaged in java.util
that can access the package private methods of TreeMap
.
After doing some more digging, I found that the default tree implementation in the JDK is a red-black tree, and its Entry
implementation look like the following:
static final class Entry<K,V> implements Map.Entry<K,V> {
K key;
V value;
Entry<K,V> left = null;
Entry<K,V> right = null;
Entry<K,V> parent;
boolean color = BLACK;
....
There doesn't seem to be any direct way to get at the root. But, if you can grab one of these Entry
ies, though, you can traverse the parent all the way up to the root, then do a traversal of the tree any way you want to get the leaves (Entry
where left == null
and right == null
). An inorder traversal would preserve the sorted ordering.
But, to reiterate, I don't see any good reason why you'd want to do this. You'd also need to do it in the java.util
package to be able to investigate those Entry
ies. But here's code, for fun. (You won't be able to execute this without overriding the security restrictions on the JVM.)
package java.util;
import java.util.TreeMap.Entry;
public class TreeMapHax {
static <K,V> List<Entry<K, V>> getLeafEntries(TreeMap<K, V> map) {
Entry<K, V> root = map.getFirstEntry();
while( root.parent != null ) root = root.parent;
List<Entry<K,V>> l = new LinkedList<Entry<K,V>>();
visitInOrderLeaves(root, l);
return l;
}
static <K,V> void visitInOrderLeaves(Entry<K, V> node, List<Entry<K, V>> accum) {
if( node.left != null ) visitInOrderLeaves(node.left, accum);
if( node.left == null && node.right == null ) accum.add(node);
if( node.right != null ) visitInOrderLeaves(node.right, accum);
}
public static void main(String[] args) {
TreeMap<String, Integer> map = new TreeMap<String, Integer>();
for( int i = 0; i < 10; i++ )
map.put(Integer.toString(i), i);
System.out.println(getLeafEntries(map));
}
}