patternjavaMinor
Class for printing class hierarchy as text
Viewed 0 times
hierarchytextprintingforclass
Problem
I'm coding a little class hierarchy printing tool for easy show hierarchies of java classes.
This is my current code:
`import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.TreeMap;
import javax.swing.JDialog;
import jdk.nashorn.internal.runtime.PropertyMap; // since Java 8, just for testing
import com.sun.javafx.collections.TrackableObservableList;
public class PrintClassHierarchy {
private static final String PADDING = " ";
private static final String PADDING_WITH_COLUMN = " | ";
private static final String PADDING_WITH_ENTRY = " |--- ";
private static final String BASE_CLASS = Object.class.getName();
private TreeMap> entries;
private boolean[] moreToCome;
public static void main(final String[] args) {
new PrintClassHierarchy().printHierarchy(
PrintStream.class,
FileOutputStream.class,
FileInputStream.class,
TrackableObservableList.class,
PropertyMap.class,
JDialog.class
);
}
public void printHierarchy(final Class... clazzes) {
// clean values
entries = new TreeMap<>();
moreToCome = new boolean[99];
// get all entries of tree
traverseClasses(clazzes);
// print collected entries as ASCII tree
printHierarchy(BASE_CLASS, 0);
}
private void printHierarchy(final String node, final int level) {
for (int i = 1; i 0) {
System.out.print(PADDING_WITH_ENTRY);
}
System.out.println(node);
if (entries.containsKey(node)) {
final List list = entries.get(node);
for (int i = 0; i ... clazzes) {
Arrays.asList(clazzes).forEach(c -> traverseClasses(c, 0));
}
private void traverseClasses(final Class clazz, final int level) {
This is my current code:
`import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.TreeMap;
import javax.swing.JDialog;
import jdk.nashorn.internal.runtime.PropertyMap; // since Java 8, just for testing
import com.sun.javafx.collections.TrackableObservableList;
public class PrintClassHierarchy {
private static final String PADDING = " ";
private static final String PADDING_WITH_COLUMN = " | ";
private static final String PADDING_WITH_ENTRY = " |--- ";
private static final String BASE_CLASS = Object.class.getName();
private TreeMap> entries;
private boolean[] moreToCome;
public static void main(final String[] args) {
new PrintClassHierarchy().printHierarchy(
PrintStream.class,
FileOutputStream.class,
FileInputStream.class,
TrackableObservableList.class,
PropertyMap.class,
JDialog.class
);
}
public void printHierarchy(final Class... clazzes) {
// clean values
entries = new TreeMap<>();
moreToCome = new boolean[99];
// get all entries of tree
traverseClasses(clazzes);
// print collected entries as ASCII tree
printHierarchy(BASE_CLASS, 0);
}
private void printHierarchy(final String node, final int level) {
for (int i = 1; i 0) {
System.out.print(PADDING_WITH_ENTRY);
}
System.out.println(node);
if (entries.containsKey(node)) {
final List list = entries.get(node);
for (int i = 0; i ... clazzes) {
Arrays.asList(clazzes).forEach(c -> traverseClasses(c, 0));
}
private void traverseClasses(final Class clazz, final int level) {
Solution
Just two quick points (for the original code):
-
You could save a lot of logic with a
This:
could be replaced with
and this:
could be replaced with
(See also: Effective Java, 2nd edition, Item 47: Know and use the libraries The author mentions only the JDK's built-in libraries but I think the reasoning could be true for other libraries too.)
-
I'd try to add a boolean parameter (
(Use more descriptive names than
-
You could save a lot of logic with a
TreeMultimap (from Google Guava):private final TreeMultimap entries = TreeMultimap.create();This:
if (entries.containsKey(node)) {
final List list = entries.get(node);
for (int i = 0; i < list.size(); i++) {
moreToCome[level] = (i < list.size() - 1);
printHierarchy(list.get(i), level + 1);
}
}could be replaced with
for (String e: list) {
moreToCome[level] = (i < list.size() - 1);
printHierarchy(e, level + 1);
i++;
}and this:
if (entries.containsKey(superName)) {
final List list = entries.get(superName);
if (!list.contains(name)) {
list.add(name);
Collections.sort(list); // SortedList
}
} else {
entries.put(superName, new ArrayList(Arrays.asList(name)));
}could be replaced with
entries.put(superName, name);(See also: Effective Java, 2nd edition, Item 47: Know and use the libraries The author mentions only the JDK's built-in libraries but I think the reasoning could be true for other libraries too.)
-
I'd try to add a boolean parameter (
lastElementInThisLevel or something similar) to the printHierarchy method to remove the moreToCome array and clean this loop:int i = 0;
for (String e: list) {
moreToCome[level] = (i < list.size() - 1);
printHierarchy(e, level + 1);
i++;
}(Use more descriptive names than
list and e.)Code Snippets
private final TreeMultimap<String, String> entries = TreeMultimap.create();if (entries.containsKey(node)) {
final List<String> list = entries.get(node);
for (int i = 0; i < list.size(); i++) {
moreToCome[level] = (i < list.size() - 1);
printHierarchy(list.get(i), level + 1);
}
}for (String e: list) {
moreToCome[level] = (i < list.size() - 1);
printHierarchy(e, level + 1);
i++;
}if (entries.containsKey(superName)) {
final List<String> list = entries.get(superName);
if (!list.contains(name)) {
list.add(name);
Collections.sort(list); // SortedList
}
} else {
entries.put(superName, new ArrayList<String>(Arrays.asList(name)));
}entries.put(superName, name);Context
StackExchange Code Review Q#46032, answer score: 5
Revisions (0)
No revisions yet.